本文主要是介绍SpringBoot集成Netty,Handler中@Autowired注解为空,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近建了个技术交流群,然后好多小伙伴都问关于Netty的问题,尤其今天的问题最特殊,功能大概是要在Netty接收消息时把数据写入数据库,那个小伙伴用的是 Spring Boot + MyBatis + Netty,所以就碰到了Handler中@Autowired注解为空的问题
参考了一些大神的博文,Spring Boot非controller使用@Autowired注解注入为null的问题,得到结论:
三个要素
- 1、用@Component注解把类设置为组件
@Component
public ClassName class;
- 2、在方法上面加@PostConstruct注解
@PostConstructpublic void init() {mclass = this;}
然后就可以用ServerImpl的接口了
@AutowiredServerImpl serviceImplmclass.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);}@Overridepublic 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 {@Overridepublic void channelActive(ChannelHandlerContext ctx) {}@Overridepublic 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());}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) {System.out.println("offline " + ctx.channel().remoteAddress());}}
搞定!
Demo【SpbNetty】地址 https://gitee.com/ichampion/Public-Project-Demo.git
这篇关于SpringBoot集成Netty,Handler中@Autowired注解为空的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!