如何在Netty中註解使用Service或者Mapper
Netty註解使用Service或Mapper
SpringBoot搭配Netty使用,在Handler中註解使用Service/Mapper 一直 為null。起初使用 SpringBoot啟動類繼承ApplicationContextAware,再寫一個靜態方法獲取Bean來解決。
放在服務器上跑瞭幾個小時就出現瞭問題,好像是該方案造成的。
另辟蹊徑,再看網上給出的答案,因為 Handler 是 new出來的,不被Spring管理,所以註解根本就沒有什麼作用。
思前想後,(有BUG,下文修正解決:覺得可以給Handler添加@Component 註解交給Spring 管理,再通過構造方法把 Handler 傳遞給Server。結構代碼):
Handler
@Component public class OBDHandler extends ChannelInboundHandlerAdapter { private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private OBDMapper mOBDMapper; }
Server
public class OBDServer { private Logger log = LoggerFactory.getLogger(getClass()); private OBDHandler obdHandler; private int port; public OBDServer(int port,OBDHandler obdHandler) { this.port = port; this.obdHandler = obdHandler; } private void bind() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(group)// .channel(NioServerSocketChannel.class) // .childHandler(new ChannelInitializer<SocketChannel>() { // @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024*1024,0,4)); ch.pipeline().addLast(obdHandler); } }); } }
創建Server
@Configuration public class NettyConfig { @Autowired private OBDHandler obdHandler; @Bean public OBDServer obdServer(){ OBDServer obdServer = new OBDServer(7788,obdHandler); obdServer.startServer(); return obdServer; } }
二次修訂
並發需要創建多個Handler,而被Spring托管的單例Handler會造成以下錯誤:
is not a @Sharable handler, so can't be added or removed multiple times.
最終通過在Server中註入 Service/Mapper,再通過Handler構造傳遞:
public class OBDServer { @Autowired private OBDMapper mOBDMapper; public OBDServer(int port) { this.port = port; } private void bind() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(group)// .channel(NioServerSocketChannel.class) // .childHandler(new ChannelInitializer<SocketChannel>() { // @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024*1024,0,4)); ch.pipeline().addLast(new OBDHandler(mOBDMapper)); } }); } }
Netty handler註入service為空
註入方式
@Slf4j @Component public class BootNettyChannelInboundHandlerAdapter extends ChannelInboundHandlerAdapter { public static BootNettyChannelInboundHandlerAdapter bootNettyChannelInboundHandlerAdapter; //1.正常註入[記得主類也需要使用@Component註解] @Autowired private DeviceUpService deviceUpService; //2.初始化構造方法一定要有 public BootNettyChannelInboundHandlerAdapter() { } //3.容器初始化的時候進行執行-這裡是重點 @PostConstruct public void init() { bootNettyChannelInboundHandlerAdapter = this; bootNettyChannelInboundHandlerAdapter.deviceUpService = this.deviceUpService; } }
完成以上步驟後通過
bootNettyChannelInboundHandlerAdapter.deviceUpService
調用service類即可
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Netty結合Protobuf進行編解碼的方法
- 在SpringBoot中,如何使用Netty實現遠程調用方法總結
- Netty解決 TCP 粘包拆包的方法
- 在netty中使用native傳輸協議的方法
- Java基於Netty實現Http server的實戰