SpringBoot集成Netty,Handler中@Autowired注解为空

本文介绍如何解决Netty的Handler中@Autowired注解失效的问题,并通过实例演示如何将接收到的消息存入数据库,涉及SpringBoot、MyBatis及Netty的集成方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近建了个技术交流群,然后好多小伙伴都问关于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

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值