[TOC]java
上一篇講了netty的一個入門的demo;項目上我也把數據處理作好了,就要開始存數據庫了;我用的mybatis框架,若是單獨使用仍是以爲比較麻煩,因此就用了springboot+mybatis+netty;本篇主要講netty與springboot的整合,以及我在這個過程當中遇到的問題,又是怎麼去解決的;git
我在作springboot與netty整合的時候在谷歌,百度找了無數文章,都沒有一篇是本身想要的,也達不到本身所想的目的;github
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
複製代碼
其實能夠複製上一篇文章的netty的三個服務類,作一些稍微的修改就好了;這裏爲了方便演示,且修都是改好了的,就直接貼出來了;spring
@Component
public class DiscardServer {
@Resource
private ChildChannelHandler childChannelHandler;
public void run(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
System.out.println("準備運行端口:" + port);
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(childChannelHandler);
//綁定端口,同步等待成功
ChannelFuture f = bootstrap.bind(port).sync();
//等待服務監聽端口關閉
f.channel().closeFuture().sync();
} finally {
//退出,釋放線程資源
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
複製代碼
@Component
public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Resource
private DiscardServerHandler discardServerHandler;
public void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(discardServerHandler);
}
}
複製代碼
3.DiscardServerHandler類數據庫
特別注意DiscardServerHandler類上須要加@Sharable註解,若是不加的話會報錯;bootstrap
@Component
@Sharable
public class DiscardServerHandler extends ChannelHandlerAdapter {
@Resource
private BaseService baseService;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
ByteBuf in = (ByteBuf) msg;
System.out.println("傳輸內容是");
System.out.println(in.toString(CharsetUtil.UTF_8));
//這裏調用service服務
baseService.test();
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 出現異常就關閉
cause.printStackTrace();
ctx.close();
}
}
複製代碼
1.BaseService接口springboot
public interface BaseService {
/** * 測試接口 */
void test();
}
複製代碼
2.接口實現類BaseServiceImpl:mybatis
@Service
public class BaseServiceImpl implements BaseService {
@Override
public void test() {
System.out.println("調用service服務");
}
}
複製代碼
我也百度到了幾篇文章說實現CommandLineRunner接口,因此我用了springboot啓動類實現CommandLineRunner接口的run方法,而後在run方法裏啓動netty服務框架
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Resource
private DiscardServer discardServer;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
discardServer.run(8080);
}
}
複製代碼
寫一個能發送數據的socket就能夠了;socket
發送的數據爲:
public static void main(String[] args){
try {
Socket socket=new Socket("localhost",8080);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
printWriter.write("$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$");
printWriter.flush();
socket.shutdownOutput();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
複製代碼
個人測試結果:
傳輸內容是
$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$
aaaaa
複製代碼
到這裏,netty與springboot的整合就完成了;
我使用springboot結合netty的流程
springboot啓動類中啓動netty啓動類(DiscardServer),netty啓動類(DiscardServer)再調用初始化channel類(ChildChannelHandler),而後初始化channel類再調用(DiscardServerHandler)類;而後DiscardServerHandler類再調用service服務;以下示例圖:
問題:
以上總結起來的問題就是我在springboot整合netty的過程當中有其中一處的調用其餘類時使用的方式是new構造的,這樣雖然springboot能啓動,netty也能啓動,可是netty服務中使用new構造的那個類中沒法依賴注入,會報空指針異常;
舉個栗子:在圖中的過程當中,我在ChildChannelHandler類中經過new的方式調用DiscardServerHandler類,其餘的過程都是使用注入的方式調用,就會出現上邊的問題;
在遇到空指針的時候,我把spring託管的bean打印了出來,全部的類都在spring的託管中,可是就是沒法注入,我也一直沒有明白怎麼回事,最後用了一個極端的方法,就是在調用服務時,獲取spring的上下文,而後再根據名字來獲取bean,你谷歌或百度:非託管類調用spring託管類,就能找到不少文章了;雖然用這個方式能解決上述的問題,但老是很差的;
最後的解決辦法:因此類之間的調用都使用spring的依賴注入,別用new的方式來調用或者靜態方法的方式調用
既然項目中用到了spring,那麼類與類之間的調用就用依賴注入,否則會報空指針的問題(就是非託管對象調用spring託管對象);這也算是一個常識性的問題了,只是本身如今才遇到這樣的問題,仍是要踩坑才能遇漲記性啊;這些問題困擾了我兩三天,仍是要有經驗的人帶,若是有經驗的人帶的話,說不幾分鐘就搞定了;
netty的文章到這裏就告一段落了,接下來就是趕項目了;哈哈;