SpringBoot整合Netty,Handler中@Autowired註解為空
阿新 • • 發佈:2018-12-17
最近建了個技術交流群,然後好多小夥伴都問關於Netty的問題,尤其今天的問題最特殊,功能大概是要在Netty接收訊息時把資料寫入資料庫,那個小夥伴用的是 Spring Boot + MyBatis + Netty,所以就碰到了Handler中@Autowired註解為空的問題
參考了一些大神的博文,Spring Boot非controller使用@Autowired註解注入為null的問題,得到結論:
三個要素
- 1、用@Component註解把類設定為元件
@Component
public ClassName class;
- 2、在方法上面加@PostConstruct註解
@PostConstruct
public void init() {
mclass = this;
}
然後就可以用ServerImpl的介面了
@Autowired
ServerImpl serviceImpl
mclass.serviceImpl.add(Pojo pojo);
但是,在這個case裡面,這一套不好用了!!!就這麼神奇…
那最後還是要自己去Spring容器獲取Bean
首先改造一下Application,實現ApplicationContextAware介面,這裡這樣寫是考慮到使用完還要釋放,所以寫的比較複雜
import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @SpringBootApplication public class SpbNettyApplication implements ApplicationContextAware { private static ApplicationContext applicationContext; private static DefaultListableBeanFactory defaultListableBeanFactory; public static void main(String[] args) { SpringApplication.run(SpbNettyApplication.class, args); new EchoServer().start(1234); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; defaultListableBeanFactory = (DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory(); } public static <T> T getBean(Class<T> clazz) { BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz); String className = clazz.getName(); defaultListableBeanFactory.registerBeanDefinition(className, beanDefinitionBuilder.getBeanDefinition()); return (T) applicationContext.getBean(className); } public static void destroy(String className){ defaultListableBeanFactory.removeBeanDefinition(className); System.out.println("destroy " + className); } }
這時候就可以在Netty的Handler中為所欲為啦!
import com.avanty.spbnetty.pojo.Car;
import com.avanty.spbnetty.service.CarServiceImpl;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class EchoHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg){
System.out.println(ctx.channel().remoteAddress() + " " + msg.toString());
ctx.channel().write("recv : " + msg.toString());
ctx.channel().flush();
Car car = new Car();
car.setCarBrand("Mustang");
car.setCarNum("789632");
CarServiceImpl carServiceImpl = SpbNettyApplication.getBean(CarServiceImpl.class);
carServiceImpl.addCar(car);
SpbNettyApplication.destroy(CarServiceImpl.class.getName());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
System.out.println("offline " + ctx.channel().remoteAddress());
}
}
搞定!
Demo【SpbNetty】地址 https://gitee.com/ichampion/Public-Project-Demo.git
#寫在最後
如果看完這篇部落格,對你有幫助的話,歡迎加入全棧技術交流群,群內不定時釋出熱門學習資料,也歡迎進行技術交流,對我的部落格有疑問也可以在群裡@我。《全棧技術交流群歡迎你》