一 前言

springboot 如何集成netty实现mapper调用不为null的问题让好多读者都头疼过,知识追寻者发了一点时间做了个基本入门集成应用给读者们指明条正确的集成方式,我相信,只要你有netty入门应用知识和spring框架基本知识,这篇文章对你将收益终身。随手点赞谢谢,如果是知识追寻者的忠粉记得分享哟。

二 pom.xml

来看看知识追寻者引入了哪些依赖

  1. netty-all 所有netty相关的包,知识追寻者这边用的非发布版本,读者可以自行更替
  2. postgresql驱动依赖,用什么数据库都没关系,读者可以换成mysql驱动
  3. mybatis-spring-boot-starte 集成mybatis需要用到的启动器
  4. druid-spring-boot-starte 当前主流性能较好的连接池,这篇文章没用到
  5. spring-boot-starter-test 测试类,这篇文章应该没用到测试
  6. 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

  1. 首先我们这边使用的固定监听端口8080
  2. 配置两个线程组 parentGroup, childGroup
  3. 注入childChannelHandler 具体可以看第四节
  4. 定义了空参init的方法,标注注解@PostConstruct,这边需要对这个注解进行一个详细介绍;在依赖注入完成初始化后,如果一个方法有该注解就将会被执行;那到底什么时候执行呢?是在类进入service之前,被该注解标注的方法会被执行,并且只会执行一次;在使用这个注解时还有一个注意点就是所有的类都必须支持依赖注入,否则会报错,一般情况下仅支持空参;
  5. init方法中就是netty的辅助启动,配置处理类,进行同步阻塞操作;
  6. 最后看下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

  1. ChildChannelHandler 类继承ChannelInitializer
  2. 注入NettyServerHandler,具体看第五节
  3. 实现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

  1. NettyServerHandler 继承ChannelHandlerAdapter
  2. 分别实现channelRead,channelReadComplete, exceptionCaught 方法
  3. 注入 NettyMapper ,自定义的mapper
  4. 重点在 channelRead 中 读取监听8080客户端发送的数据,然后写入zszxz-66666构建响应
  5. 如果mapper为空 会打印 can you believe that the mapper is null
  6. 最后执行回调处理;
/**
* @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);
} }

九 执行结果

  1. 发送了知识追寻者好棒棒
  2. 响应 zszxz-66666

十 结语

最后祝贺读者们新年快乐,预防流感病毒,出门带口罩,不去人流量大的地方,吃熟肉,勤洗手;理性对待网上关于新型流感病毒,一起为中国加油,为武汉加油;过年也不要忘记学习哟,知识追寻者要贯彻每天都学习的方针,坚定不移的追随读者的步伐;

netty集成springboot的更多相关文章

  1. Spring Maven项目集成Springboot

    Maven管理的Spring项目,准备集成Springboot做接口 1.Springboot对Spring有版本要求 我用的Springboot版本:1.4.5.RELEASE,对应Spring的版 ...

  2. netty 集成 wss 安全链接

    netty集成ssl完整参考指南(含完整源码) 虽然我们在内部rpc通信中使用的是基于认证和报文头加密的方式实现安全性,但是有些时候仍然需要使用SSL加密,可能是因为对接的三方系统需要,也可能是由于o ...

  3. 基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇

    基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇 前提 最近对网络编程方面比较有兴趣,在微服务实践上也用到了相对主流的RPC框架如Spring Cloud Gateway底层也切换 ...

  4. 基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇

    前提 前置文章: Github Page:<基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> Coding Page:<基于Netty和SpringBoot实现 ...

  5. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client篇

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> 前 ...

  6. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...

  7. 实战:docker搭建FastDFS文件系统并集成SpringBoot

    实战:docker搭建FastDFS文件系统并集成SpringBoot 前言 15年的时候,那时候云存储还远远没有现在使用的这么广泛,归根结底就是成本和安全问题,记得那时候我待的公司是做建站开发的,前 ...

  8. Netty(一) SpringBoot 整合长连接心跳机制

    前言 Netty 是一个高性能的 NIO 网络框架,本文基于 SpringBoot 以常见的心跳机制来认识 Netty. 最终能达到的效果: 客户端每隔 N 秒检测是否需要发送心跳. 服务端也每隔 N ...

  9. netty集成ssl完整参考指南(含完整源码)

    虽然我们在内部rpc通信中使用的是基于认证和报文头加密的方式实现安全性,但是有些时候仍然需要使用SSL加密,可能是因为对接的三方系统需要,也可能是由于open的考虑.中午特地测了下netty下集成ss ...

随机推荐

  1. JVM中的动态语言支持简介

    抽丝剥茧 细说架构那些事——[优锐课] 从版本6开始,JVM已扩展为支持现代动态语言(也称为脚本语言).Java8的发行为这一领域提供了更多动力.感到这种支持的必要性是因为Java作为一种语言固有地是 ...

  2. C#系统库的源代码

    .NET Core:https://github.com/dotnet/corefx .NET Framework:https://referencesource.microsoft.com

  3. jmeter巧用自增长型变量

    实现目的 在进行性能测试时,某些请求中的参数值并不允许被重复使用,比如账号的创建.开通授权等服务,这时就需要在jmeter中构造一些自增长型的变量,供后续请求使用,以解决参数值重复的问题. 脚本实现 ...

  4. web项目获取路径

    Java获取路径的各种方法:  (1).request.getRealPath("/"); //不推荐使用获取工程的根路径 (2).request.getRealPath(requ ...

  5. RocketMQ-0.1

    rocketmq的主要部分是由4种集群构成的:namesrv集群.broker集群.producer集群和consumer集群. namesrv集群:也就是注册中心,rocketmq在注册中心这块没有 ...

  6. java多线程信息共享

    上篇文章知识介绍了多线程的创建和启动问题,各个子线程和子线程或者说子线程和main线程没有信息的交流,这篇文章主要探讨线程之间信息共享以及交换问题.这篇文章主要以一个卖票例子来展开. 继承Thread ...

  7. JS高级---原型的简单的语法

    原型的简单的语法 构造函数,通过原型添加方法,以下语法,手动修改构造器的指向 实例化对象,并初始化,调用方法 <!DOCTYPE html> <html lang="en& ...

  8. SDNU_ACM_ICPC_2020_Winter_Practice_2nd

    A - [The__Flash]的矩阵 给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大. Input输入数据的第一行为一个正整数T,表示有T组测试数据.每一组测试数据 ...

  9. java使用bitmap求两个数组的交集

    一般来说int代表一个数字,但是如果利用每一个位 ,则可以表示32个数字 ,在数据量极大的情况下可以显著的减轻内存的负担.我们就以int为例构造一个bitmap,并使用其来解决一个简单的问题:求两个数 ...

  10. netty(八)buffer源码学习3

    问题 : compositeByteBuf 是干什么和其他 compositeByteBuf 有何区别 内部实现 概述 compositeByteBuf 就像数据库中的视图,把几个表的字段组合在一起, ...