netty集成springboot
一 前言
springboot 如何集成netty实现mapper调用不为null的问题让好多读者都头疼过,知识追寻者发了一点时间做了个基本入门集成应用给读者们指明条正确的集成方式,我相信,只要你有netty入门应用知识和spring框架基本知识,这篇文章对你将收益终身。随手点赞谢谢,如果是知识追寻者的忠粉记得分享哟。
二 pom.xml
来看看知识追寻者引入了哪些依赖
- netty-all 所有netty相关的包,知识追寻者这边用的非发布版本,读者可以自行更替
- postgresql驱动依赖,用什么数据库都没关系,读者可以换成mysql驱动
- mybatis-spring-boot-starte 集成mybatis需要用到的启动器
- druid-spring-boot-starte 当前主流性能较好的连接池,这篇文章没用到
- spring-boot-starter-test 测试类,这篇文章应该没用到测试
- lombok 开发神器,节省代码开发量
<!-- springboot start 父类 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- web start配置 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
</dependencies>
三 NettyServer
- 首先我们这边使用的固定监听端口8080
- 配置两个线程组
parentGroup
,childGroup
- 注入childChannelHandler 具体可以看第四节
- 定义了空参init的方法,标注注解@PostConstruct,这边需要对这个注解进行一个详细介绍;在依赖注入完成初始化后,如果一个方法有该注解就将会被执行;那到底什么时候执行呢?是在类进入service之前,被该注解标注的方法会被执行,并且只会执行一次;在使用这个注解时还有一个注意点就是所有的类都必须支持依赖注入,否则会报错,一般情况下仅支持空参;
- init方法中就是netty的辅助启动,配置处理类,进行同步阻塞操作;
- 最后看下destory()方法,在该方法上面标注了注解@PreDestroy;@PreDestroy表示一种回调的信息通知机制,即当实例在容器中被移除的时候会做出通知;通常我们会用来做一些关闭资源句柄等操作;
/**
* @Author lsc
* <p>netty server 端 </p>
*/
@Component
public class NettyServer {
private Integer port = 8080;
// 配置线程组 实质是 reactor线程组
NioEventLoopGroup parentGroup = new NioEventLoopGroup();
// 配置线程组
NioEventLoopGroup childGroup = new NioEventLoopGroup();
@Autowired
ChildChannelHandler childChannelHandler;
@PostConstruct
public void init() throws Exception{
// 启动 NIO
ServerBootstrap serverBootstrap = new ServerBootstrap();
//
serverBootstrap.group(parentGroup,childGroup)
.channel(NioServerSocketChannel.class)// 相当于 ServerSocketChannel
.option(ChannelOption.SO_BACKLOG,1024)//TCP参数 1024 个队列
.childHandler(childChannelHandler);// 处理事件
// 绑定端口 同步阻塞等待同步成功 channelFuture 异步操作通知回调
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
// 同步阻塞等待服务监听端口关闭
channelFuture.channel().closeFuture().sync();
}
@PreDestroy
public void destory() throws InterruptedException {
// 关闭资源
parentGroup.shutdownGracefully().sync();
childGroup.shutdownGracefully().sync();
}
}
四 ChildChannelHandler
- ChildChannelHandler 类继承ChannelInitializer
- 注入NettyServerHandler,具体看第五节
- 实现initChannel 方法并且在方法用获得pipeline注入nettyServerHandler;
/**
* @Author lsc
* <p> </p>
*/
@Component
public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Autowired
NettyServerHandler nettyServerHandler;
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//
pipeline.addLast(nettyServerHandler);
}
}
五 NettyServerHandler
- NettyServerHandler 继承ChannelHandlerAdapter
- 分别实现channelRead,channelReadComplete, exceptionCaught 方法
- 注入 NettyMapper ,自定义的mapper
- 重点在 channelRead 中 读取监听8080客户端发送的数据,然后写入zszxz-66666构建响应
- 如果mapper为空 会打印
can you believe that the mapper is null
- 最后执行回调处理;
/**
* @Author lsc
* <p> 处理类 </p>
*/
@Slf4j
@Component
public class NettyServerHandler extends ChannelHandlerAdapter {
@Autowired
NettyMapper mapper;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("-----handler-------");
// 转为字节缓冲区
ByteBuf buf = (ByteBuf)msg;
// 字节数组
byte[] bytes = new byte[buf.readableBytes()];
// 缓冲区数据读入字节数组
buf.readBytes(bytes);
// 编码转为字符串
String body = (new String(bytes, "UTF-8"));
System.out.println(" get the data from client : " + body);
// 构造响应数据
String responseData = "zszxz-66666";
// 数据写入缓冲区
ByteBuf resp = Unpooled.copiedBuffer(responseData.getBytes());
// 写入数据响应
ChannelFuture channelFuture = ctx.writeAndFlush(resp);
if (mapper==null){
System.out.println("can you believe that the mapper is null");
}
List<Map> user = mapper.getUser();
System.out.println(user);
// 回调处理
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()){
log.info("success");
}else {
log.error("error");
}
}
});
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// 写入 seocketChannel
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 异常关闭资源句柄
ctx.close();
}
}
六 mapper
6.1 mapper接口
mapper接口中定义了一个查询方法,获得用户;
@Mapper
@Repository
public interface NettyMapper {
List<Map> getUser();
}
6.2 mapper映射器
查询所有学生
<mapper namespace="com.zszxz.netty.mapper.NettyMapper">
<select id="getUser" resultType="map">
select * from "student"
</select>
</mapper>
七 application.yml
spring:
datasource:
druid:
#本地
url: jdbc:postgresql://localhost:5432/springboot
username: postgres
password: 123456
driver-class-name: org.postgresql.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
mapUnderscoreToCamelCase: true
八 启动类
/**
* @Author lsc
* <p> 知识追寻者netty系列</p>
*/
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
九 执行结果
- 发送了知识追寻者好棒棒
- 响应 zszxz-66666
十 结语
最后祝贺读者们新年快乐,预防流感病毒,出门带口罩,不去人流量大的地方,吃熟肉,勤洗手;理性对待网上关于新型流感病毒,一起为中国加油,为武汉加油;过年也不要忘记学习哟,知识追寻者要贯彻每天都学习的方针,坚定不移的追随读者的步伐;
netty集成springboot的更多相关文章
- Spring Maven项目集成Springboot
Maven管理的Spring项目,准备集成Springboot做接口 1.Springboot对Spring有版本要求 我用的Springboot版本:1.4.5.RELEASE,对应Spring的版 ...
- netty 集成 wss 安全链接
netty集成ssl完整参考指南(含完整源码) 虽然我们在内部rpc通信中使用的是基于认证和报文头加密的方式实现安全性,但是有些时候仍然需要使用SSL加密,可能是因为对接的三方系统需要,也可能是由于o ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇
基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇 前提 最近对网络编程方面比较有兴趣,在微服务实践上也用到了相对主流的RPC框架如Spring Cloud Gateway底层也切换 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇
前提 前置文章: Github Page:<基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> Coding Page:<基于Netty和SpringBoot实现 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Client篇
前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> 前 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理
前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...
- 实战:docker搭建FastDFS文件系统并集成SpringBoot
实战:docker搭建FastDFS文件系统并集成SpringBoot 前言 15年的时候,那时候云存储还远远没有现在使用的这么广泛,归根结底就是成本和安全问题,记得那时候我待的公司是做建站开发的,前 ...
- Netty(一) SpringBoot 整合长连接心跳机制
前言 Netty 是一个高性能的 NIO 网络框架,本文基于 SpringBoot 以常见的心跳机制来认识 Netty. 最终能达到的效果: 客户端每隔 N 秒检测是否需要发送心跳. 服务端也每隔 N ...
- netty集成ssl完整参考指南(含完整源码)
虽然我们在内部rpc通信中使用的是基于认证和报文头加密的方式实现安全性,但是有些时候仍然需要使用SSL加密,可能是因为对接的三方系统需要,也可能是由于open的考虑.中午特地测了下netty下集成ss ...
随机推荐
- 1+x证书Web 前端开发初级——理论考试(试卷1)
1+x证书Web 前端开发初级——理论考试(试卷1) 一.单选题(每小题 2 分,共 30 小题,共 60 分) 1.HTML 语言中,设置表格中文字与边框距离的标签是() A.<table b ...
- kuangbin专题 专题九 连通图 Critical Links UVA - 796
题目链接:https://vjudge.net/problem/UVA-796 题目:裸的求桥,按第一个元素升序输出即可. #include <iostream> #include < ...
- Bootstrap环境安装加使用---开启Bootstrap 之旅
1.首先去Bootstrap官网https://getbootstrap.com/上下载Bootstrap 的最新版本 对应的中文页面如下: 下载自己所需要的版本(目前我自己下载的是编译的css和js ...
- 【音乐欣赏】《PANTA RHEI》 - MYTH & ROID
曲名:PANTA RHEI 作者:MYTH & ROID [ti:PANTA RHEI (<异世界超能魔术师>TV动画片头曲)] [ar:MYTH & ROID] [al: ...
- Codeforces Round #610 (Div. 2)C(贪心,思维)
沿时间轴枚举,发现关键时间点在于新题目被锁定的前一时间,那是新的题目还没有被锁定并且距离旧的题目已经被锁定的最晚时间,对这些时间点进行操作 #define HAVE_STRUCT_TIMESPEC # ...
- Python turtle库详解
Python turtle库详解 Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制,在 ...
- Mac配置内网穿透
闲语: Java开发过程中,往往会对接第三方,而在对接过程中,双方间使用的最多的"通讯"方式就是异步通知.可是异步通知过程中,只能通知到外网地址,可是在调试过程我们都是在本地进行- ...
- ARM架构安装Anaconda3出现错误:cannot execute binary file: Exec format error
ARM架构安装Anaconda3出现错误:cannot execute binary file: Exec format error 原因是:安装包格式不对. 在Anaconda官网上只有x86(32 ...
- red hat 报错:apt-get:找不到命令
Linux有两个系列:一个是RedHat系列,一个是Debian系列. RedHat系列:Redhat.Centos.Fedora等 Debian系列:Debian.Ubuntu等 RedHat 系列 ...
- console.log 如何打印对象
问题描述: var obj={a:1,b:2}; console.log(obj); 控制台返回的值是object. 解决方案: console.log(JSON.stringify(obj))