netty里集成spring注入mysq连接池(一)
netty的性能非常高,能达到8000rps以上,见
各个web服务器的性能对比测试
1.准备好需要的jar包
- spring.jar //spring包
- netty-3.2.4.Final.jar // netty库
- commons-dbcp.jar // dbcp数据库连接池
- mysql-connector-java-5.1.6.jar // dbcp数据库连接池需要依赖
- commons-logging.jar //spring.jar需要依赖
- commons-pool.jar // dbcp数据库连接池需要依赖
2.新建java工程TestNettyServer
2.1导入netty的例子
HttpServer.java
- package org.jboss.netty.example.http.snoop;
- import java.net.InetSocketAddress;
- import java.util.concurrent.Executors;
- import org.jboss.netty.bootstrap.ServerBootstrap;
- import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
- public class HttpServer {
- public static void main(String[] args) {
- // Configure the server.
- ServerBootstrap bootstrap = new ServerBootstrap(
- new NioServerSocketChannelFactory(
- Executors.newCachedThreadPool(),
- Executors.newCachedThreadPool()));
- // Set up the event pipeline factory.
- bootstrap.setPipelineFactory(new HttpServerPipelineFactory());
- // Bind and start to accept incoming connections.
- bootstrap.bind(new InetSocketAddress(8081));
- }
- }
HttpServerPipelineFactory.java
- package org.jboss.netty.example.http.snoop;
- import static org.jboss.netty.channel.Channels.*;
- import org.jboss.netty.channel.ChannelPipeline;
- import org.jboss.netty.channel.ChannelPipelineFactory;
- import org.jboss.netty.handler.codec.http.HttpContentCompressor;
- import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
- import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
- public class HttpServerPipelineFactory implements ChannelPipelineFactory {
- public ChannelPipeline getPipeline() throws Exception {
- // Create a default pipeline implementation.
- ChannelPipeline pipeline = pipeline();
- // Uncomment the following line if you want HTTPS
- //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
- //engine.setUseClientMode(false);
- //pipeline.addLast("ssl", new SslHandler(engine));
- pipeline.addLast("decoder", new HttpRequestDecoder());
- // Uncomment the following line if you don't want to handle HttpChunks.
- //pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
- pipeline.addLast("encoder", new HttpResponseEncoder());
- // Remove the following line if you don't want automatic content compression.
- pipeline.addLast("deflater", new HttpContentCompressor());
- pipeline.addLast("handler", new HttpRequestHandler());
- return pipeline;
- }
- }
HttpRequestHandler.java
- package org.jboss.netty.example.http.snoop;
- import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
- import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
- import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
- import static org.jboss.netty.handler.codec.http.HttpVersion.*;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Set;
- import org.jboss.netty.buffer.ChannelBuffer;
- import org.jboss.netty.buffer.ChannelBuffers;
- import org.jboss.netty.channel.ChannelFuture;
- import org.jboss.netty.channel.ChannelFutureListener;
- import org.jboss.netty.channel.ChannelHandlerContext;
- import org.jboss.netty.channel.ExceptionEvent;
- import org.jboss.netty.channel.MessageEvent;
- import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
- import org.jboss.netty.handler.codec.http.Cookie;
- import org.jboss.netty.handler.codec.http.CookieDecoder;
- import org.jboss.netty.handler.codec.http.CookieEncoder;
- import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
- import org.jboss.netty.handler.codec.http.HttpChunk;
- import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
- import org.jboss.netty.handler.codec.http.HttpRequest;
- import org.jboss.netty.handler.codec.http.HttpResponse;
- import org.jboss.netty.handler.codec.http.QueryStringDecoder;
- import org.jboss.netty.util.CharsetUtil;
- /**
- * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
- * @author Andy Taylor (andy.taylor@jboss.org)
- * @author <a href="http://gleamynode.net/">Trustin Lee</a>
- *
- * @version $Rev: 2368 $, $Date: 2010-10-18 17:19:03 +0900 (Mon, 18 Oct 2010) $
- */
- public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
- private HttpRequest request;
- private boolean readingChunks;
- /** Buffer that stores the response content */
- private final StringBuilder buf = new StringBuilder();
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- if (!readingChunks) {
- HttpRequest request = this.request = (HttpRequest) e.getMessage();
- if (is100ContinueExpected(request)) {
- send100Continue(e);
- }
- buf.setLength(0);
- buf.append("WELCOME TO THE WILD WILD WEB SERVER\r\n");
- buf.append("===================================\r\n");
- buf.append("VERSION: " + request.getProtocolVersion() + "\r\n");
- buf.append("HOSTNAME: " + getHost(request, "unknown") + "\r\n");
- buf.append("REQUEST_URI: " + request.getUri() + "\r\n\r\n");
- for (Map.Entry<String, String> h: request.getHeaders()) {
- buf.append("HEADER: " + h.getKey() + " = " + h.getValue() + "\r\n");
- }
- buf.append("\r\n");
- QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());
- Map<String, List<String>> params = queryStringDecoder.getParameters();
- if (!params.isEmpty()) {
- for (Entry<String, List<String>> p: params.entrySet()) {
- String key = p.getKey();
- List<String> vals = p.getValue();
- for (String val : vals) {
- buf.append("PARAM: " + key + " = " + val + "\r\n");
- }
- }
- buf.append("\r\n");
- }
- if (request.isChunked()) {
- readingChunks = true;
- } else {
- ChannelBuffer content = request.getContent();
- if (content.readable()) {
- buf.append("CONTENT: " + content.toString(CharsetUtil.UTF_8) + "\r\n");
- }
- writeResponse(e);
- }
- } else {
- HttpChunk chunk = (HttpChunk) e.getMessage();
- if (chunk.isLast()) {
- readingChunks = false;
- buf.append("END OF CONTENT\r\n");
- HttpChunkTrailer trailer = (HttpChunkTrailer) chunk;
- if (!trailer.getHeaderNames().isEmpty()) {
- buf.append("\r\n");
- for (String name: trailer.getHeaderNames()) {
- for (String value: trailer.getHeaders(name)) {
- buf.append("TRAILING HEADER: " + name + " = " + value + "\r\n");
- }
- }
- buf.append("\r\n");
- }
- writeResponse(e);
- } else {
- buf.append("CHUNK: " + chunk.getContent().toString(CharsetUtil.UTF_8) + "\r\n");
- }
- }
- }
- private void writeResponse(MessageEvent e) {
- // Decide whether to close the connection or not.
- boolean keepAlive = isKeepAlive(request);
- // Build the response object.
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- response.setContent(ChannelBuffers.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
- response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
- if (keepAlive) {
- // Add 'Content-Length' header only for a keep-alive connection.
- response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
- }
- // Encode the cookie.
- String cookieString = request.getHeader(COOKIE);
- if (cookieString != null) {
- CookieDecoder cookieDecoder = new CookieDecoder();
- Set<Cookie> cookies = cookieDecoder.decode(cookieString);
- if(!cookies.isEmpty()) {
- // Reset the cookies if necessary.
- CookieEncoder cookieEncoder = new CookieEncoder(true);
- for (Cookie cookie : cookies) {
- cookieEncoder.addCookie(cookie);
- }
- response.addHeader(SET_COOKIE, cookieEncoder.encode());
- }
- }
- // Write the response.
- ChannelFuture future = e.getChannel().write(response);
- // Close the non-keep-alive connection after the write operation is done.
- if (!keepAlive) {
- future.addListener(ChannelFutureListener.CLOSE);
- }
- }
- private void send100Continue(MessageEvent e) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, CONTINUE);
- e.getChannel().write(response);
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
- throws Exception {
- e.getCause().printStackTrace();
- e.getChannel().close();
- }
- }
DatabaseUtil.java
- package org.jboss.netty.example.http.snoop;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import org.apache.commons.dbcp.BasicDataSource;
- /**
- * 连接和使用数据库资源的工具类
- *
- * @author yifangyou
- * @version gtm 2010-09-27
- */
- public class DatabaseUtil {
- /**
- * 数据源
- */
- private BasicDataSource dataSource;
- /**
- * 数据库连接
- */
- public Connection conn;
- /**
- * 获取数据源
- * @return 数据源
- */
- public BasicDataSource getDataSource() {
- return dataSource;
- }
- /**
- * 设置数据源
- * @param dataSource 数据源
- */
- public void setDataSource(BasicDataSource dataSource) {
- this.dataSource = dataSource;
- }
- /**
- * 获取数据库连接
- * @return conn
- */
- public Connection getConnection() {
- try {
- conn = dataSource.getConnection();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- return conn;
- }
- /**
- * 关闭数据库连接
- * @param conn
- */
- public void closeConnection(Connection conn) {
- if (null != conn) {
- try {
- conn.close();
- conn = null;
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 获取执行SQL的工具
- * @param conn 数据库连接
- * @param sql SQL语句
- * @return prepStmt
- */
- public PreparedStatement getPrepStatement(Connection conn, String sql) {
- PreparedStatement prepStmt = null;
- try {
- prepStmt = conn.prepareStatement(sql);
- } catch (SQLException e) {
- e.printStackTrace();
- }
- return prepStmt;
- }
- /**
- * 关闭数据库资源
- * @param prepStmt
- */
- public void closePrepStatement(PreparedStatement prepStmt) {
- if (null != prepStmt) {
- try {
- prepStmt.close();
- prepStmt = null;
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
2.2 导入jar包
在工程下添加lib目录
把jar包拷进去
点击工程的右键“propertis”->Java Build Path->Libraries->Add JARS
3.分析如何注入
Netty的运行过程是
因此我们需要
Spring注入入口在HttpServer里的main函数
把HttpRequestHandler注入到HttpServerPipelineFactory,
把HttpServerPipelineFactory注入到HttpServer
另外我们在HttpRequestHandler需要用到mysql连接池,因此还要把mysql连接池注入到HttpRequestHandler
转载于:https://blog.51cto.com/yifangyou/622607
相关文章:

图很难理解?看这篇图论基础与图存储结构就够了
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑作者 | 程序员吴师兄转载自五分钟学算法(ID:CXYxiaowu)1 前言打算先普及一下图的相关理论支持,本文不建议一口气阅读完毕,可以先浏览一遍&a…

【Linux】修改/etc/fstab时参数设错,导致启动异常,无法进入系统(已解决)
1、问题描述 在ubuntu14.04上设置自动挂载硬盘分区时,修改/etc/fstab时,将defaults错误写成default,导致启动异常,无法进入系统。 2、解决方法 1)ubuntu启动时有两种模式:普通模式(ubuntu&am…

gitlab安装
根据官方文档安装:https://www.gitlab.com.cn/installation/#centos-6 centos6: 1、没有安装lokkit,yum search lokkit后安装lokkit sudo yum install -y curl policycoreutils-python openssh-server cronie sudo lokkit -s http -s ssh2、安…

如何将Android带入互联网数字家庭? 第一篇转载
前言:很有幸通过ARM Group认识了 ARM的家庭软件架构师 --- 章立(Leon Zhang) (他也是ARM战略软件联盟部门的一员. Leon 拥有多年产品开发和项目管理经验, 曾经参与了数字录像机、机顶盒、数字电视,网络电视以及智能电视࿰…

【linux】用过的shell命令
1、批量替换文件中的字符串 eg:将当前目录 . 下的old替换成new sed -i "s/new/old/g" grep old -rl .如果字符串中有‘/’等特殊字符需要反斜杠‘\’来转移 eg:将当前目录下的“old/old”,替换成“new/new” sed -i "s/new…

node简单实现excel文件下载
1.利用csv格式兼容实现 csv是一种利用,、\t、\n等分隔符存储的文本文件,excel可兼容打开,利用此原理,代码实现如下: app.use(route.get(/export, async ctx > {ctx.res.setHeader(Content-Type, application/vnd.ms-execl);ctx…

儿科医生的眼泪,全被数据看见了
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑作者 | AlfredWu来源 | Alfred数据室(ID:Alfred_Lab)《人间世》第二季第8集《儿科医生:坚守,还是逃离?》把儿科医生的辛苦与挣扎…

[毕业生的商业软件开发之路]C#类型样式
近期开始接触到在校学生、高校实习生和毕业生,在此说一下笔者对这些徘徊在职场门口的学生一些建议,希望能给这些初学者进入软件开发行业带来一些帮助,使得毕业生能更顺利的进入软件开发公司开始职场生涯,人生来一个完美的转弯。 -----------------------…

特斯拉被曝储存大量未加密个人数据 | 极客头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑编译丨王哲来源丨猎云网( ID:ilieyun)编者按:特斯拉是否明确界定了数据安全的目标?它现有的规则又在保护哪些人?如果…

【Linux】neocomplcache disabled: “sudo vim“ is detected and $HOME is set to your user‘s home
1、问题描述 使用sudo vim时,弹出提示: neocomplcache disabled: "sudo vim" is detected and $HOME is set to your users home. You may want to use the sudo.vim plugin, the "-H" option with "sudo" or set alwa…

016 | 漫谈区块链共识机制
原创文章,转载请注明:转载自Keegan小钢 并标明原文链接:http://keeganlee.me/post/blockchain/20180425 微信订阅号:keeganlee_me 写于2018-04-25 专栏地址:xiaozhuanlan.com/fullstack 共识机制是区块链的一个核心特征…

临危不乱,.Net+IIS环境经常出现的问题及排障。
http://www.cnblogs.com/CoreCaiNiao/archive/2011/08/02/2123991.html

零门槛!手把手教你打造AI应用
如你所见,聊天机器人已经逐渐渗透到生活的方方面面。它可以提供生活娱乐方面的服务,比如查询音乐、地图、天气,做心理测试,甚至 Google 的 Duplex 技术还能让你通过机器人进行订餐,当然还有很多能跟你谈天说地闲聊胡扯…

【Qt】启动QtCreator时报错:Cannot mix incompatible Qt library (version ) with this library (version...
1、问题描述 当启动QtCreator时报错(我的Qt版本是Qt5.6.3): Cannot mix incompatible Qt library (version 0x50603) with this library (version 0x50601) Aborted (core dumped)2、原因分析 原因是QtCreator使用的Qt库版本是5.6.1,而环境中配置的Qt库版本是5.6.3 1)Q…

利用IIS作为宿主 发布你的WCF Service(转)
http://blog.csdn.net/blacksource/article/details/3942130最近公司的一个需求,涉及到WCF开发。在网上找了些资料,大都是利用单独的应用程序、或者Windows服务作为WCF Service的host。其实WCF还提供一种方式,和以前的Remoting比较类似&#…

旷视提出AutoML新方法,在ImageNet取得新突破 | 技术头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑来源 | 旷视研究院 近日,来自旷视研究院的郭梓超、张祥雨、穆皓远、孙剑等人发表一篇新论文“Single Path One-Shot Neural Architecture Search with Uniform Sampling”&a…

9.QT-标准对话框
Qt提供的可复用的标准对话框,全部继承自QDialog类,如下图所示: QMessageBox:信息对话框,用于显示信息、询问问题等;QFileDialog:文件对话框QColorDialog:颜色对话框QInputDialog:输入对话框(允许用户输入一…

【Python】解决print不能立即打印的问题
1、问题描述 在Python中使用print打印hello world时,终端不显示 def hello():print("hello world!")2、原因 因为标准输入输出stdin/stdout有缓冲区,所以使用print不能立即打印出来,作为刚接触Python的菜鸟,迷瞪了半…

windows mobile做一个摄象头预览程序
zdirectshow的原理大概大家都知道,基本就是用微软封装的接口来实现硬件无关性,但是最终调用的接口都要在驱动层有对应的实现: 为了更清楚地演示directshow的数据传输过程,我必须说明的这个程序的基本流程。我采用的是vs2005 windows mobile 6。0 professional 仿真模拟器&…

初学者的机器学习入门实战教程!
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑作者 | Adrian Rosebrock译者 | kbsc13,京东算法工程师,研究领域计算机视觉来源 | 机器学习与计算机视觉(ID:AI_Developer)这是…

【Qt】调用Python函数:无参数、单个参数、多个参数、数组参数
一、链接配置 如果缺少头文件需要安装python3-dev: sudo apt-get install python3-dev链接libpython3.4库,添加头文件路径,以Qt为例: INCLUDEPATH += /usr/include/python3.4 LIBS += -L /usr/lib/python3.4/config-3.4m-x86_64-linux-gnu -lpython3.4二、头文件 因为p…

分布式系统的问题
本文内容翻译自《Designing Data-Intensive Applications》一书的第8章。 近几章主要介绍系统如何处理错误。例如,我们讨论了副本故障转移,复制滞后和事务的并发控制。当我们理解实际系统中可能出现的各种边界情况时,我们就能更好地处理它们。…

php-cgi占用cpu资源过高的解决方法
转的网上的,不过对PHP-CGI菜鸟的人,还是有点帮助的。 1. 一些php的扩展与php版本兼容存在问题,实践证明 eAccelerater与某些php版本兼容存在问题,具体表现时启动php-cgi进程后,运行10多分钟,奇慢无比&#…

请收下这份NLP热门词汇解读
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」,购票请扫码咨询 ↑↑↑本文转载自微软研究院AI头条(ID:MSRAsia)编者按:在过去的一段时间,自然语言处理领域取得了许多重要的进展,Transformer、BERT、…

【Ubuntu】dpkg: 处理软件包 XXXX (--configure)时出错解决方法
1、使用apt-get --purge remove删除安装包时报错 dpkg: 处理软件包 python-gflags (–configure)时出错: 子进程 已安装 post-installation 脚本 返回了错误号 1 正在设置 python-sklearn (0.14.1-2) … Traceback (most recent call last): File “/usr/bin/pycom…

c#devexpress GridContorl添加进度条
demo 的实现图 下边是步骤和代码 1定义 时钟事件,定时的增加进度条的增量. 2: 添加进度条 3;定义字段属性 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; …

信达充值旗舰店
在淘宝上新开了一个话费 游戏点卡充值的小店,以后大家话费没了可以联系我啊,速度还是蛮快的,都是赔本卖的只想提高点信誉,所以价格也是最最低的了,感谢大家的支持,多多帮忙啊^_^ http://sjzxinda.taobao.co…

完整代码+实操!手把手教你操作Faster R-CNN和Mask R-CNN
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑机器视觉领域的核心问题之一就是目标检测(Object Detection),它的任务是找出图像当中所有感兴趣的目标(物体),…

【Dlib】使用dlib_face_recognition_resnet_model_v1.dat无法实现微调fune-tuning
1、问题描述 dlib官方使用resnet训练人脸识别,训练了300万的数据,网络参数保存在dlib_face_recognition_resnet_model_v1.dat中。 测试中识别lfw数据时,准确率能达到99.13%,但是在识别自己的数据时,准确率有点低&…

Visual Studio 2017 - Windows应用程序打包成exe文件(1)- 工具简单总结
最近有对一个Windows应用程序少许维护和修改。修改之后要发布新的exe安装文件,打包exe文件时,遇到了很头疼的问题,还好最后解决了,记录一下。 Visual Studio版本:Visual Studio 2017 Visual Studio 2017 打包插件 新建…