如何在Netty中注解使用Service或者M(jìn)apper
Netty注解使用Service或Mapper
SpringBoot搭配Netty使用,在Handler中注解使用Service/Mapper 一直 為null。起初使用 SpringBoot啟動(dòng)類繼承ApplicationContextAware,再寫一個(gè)靜態(tài)方法獲取Bean來解決。
放在服務(wù)器上跑了幾個(gè)小時(shí)就出現(xiàn)了問題,好像是該方案造成的。
另辟蹊徑,再看網(wǎng)上給出的答案,因?yàn)?Handler 是 new出來的,不被Spring管理,所以注解根本就沒有什么作用。
思前想后,(有BUG,下文修正解決:覺得可以給Handler添加@Component 注解交給Spring 管理,再通過構(gòu)造方法把 Handler 傳遞給Server。結(jié)構(gòu)代碼):
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); ?? ??? ??? ?} ?? ??? ?}); ? ? } }
創(chuàng)建Server
@Configuration public class NettyConfig {?? ? ?? ?@Autowired ?? ?private OBDHandler obdHandler; ?? ? ?? ?@Bean ?? ?public OBDServer obdServer(){ ?? ??? ?OBDServer obdServer = new OBDServer(7788,obdHandler); ?? ??? ?obdServer.startServer(); ?? ??? ?return obdServer; ?? ?} }
二次修訂
并發(fā)需要?jiǎng)?chuàng)建多個(gè)Handler,而被Spring托管的單例Handler會(huì)造成以下錯(cuò)誤:
is not a @Sharable handler, so can't be added or removed multiple times.
最終通過在Server中注入 Service/Mapper,再通過Handler構(gòu)造傳遞:
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.初始化構(gòu)造方法一定要有 ? ? public BootNettyChannelInboundHandlerAdapter() { ? ? ? } ? ? //3.容器初始化的時(shí)候進(jìn)行執(zhí)行-這里是重點(diǎn) ? ? @PostConstruct ? ? public void init() { ? ? ? ? bootNettyChannelInboundHandlerAdapter = this; ? ? ? ? bootNettyChannelInboundHandlerAdapter.deviceUpService = this.deviceUpService; ? ? } }
完成以上步驟后通過
bootNettyChannelInboundHandlerAdapter.deviceUpService
調(diào)用service類即可
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法
本篇文章主要介紹了Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03java中List對(duì)象列表實(shí)現(xiàn)去重或取出及排序的方法
這篇文章主要介紹了關(guān)于java中List對(duì)象列表實(shí)現(xiàn)去重或取出以及排序的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08Java漢字轉(zhuǎn)拼音工具類完整代碼實(shí)例
這篇文章主要介紹了java漢字轉(zhuǎn)拼音工具類完整代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03詳解JavaEE 使用 Redis 數(shù)據(jù)庫進(jìn)行內(nèi)容緩存和高訪問負(fù)載
本篇文章主要介紹了JavaEE 使用 Redis 數(shù)據(jù)庫進(jìn)行內(nèi)容緩存和高訪問負(fù)載,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08