SpringBoot在某些框架 如netty的handler类中注入依赖报null异常

SpringBoot在某些框架 如netty的handler类中注入依赖报null异常


spring在使用一些安全或者通信框架,如netty,t-io,spring-security时,总会遇到一些handler处理类,而在这些类中往往无法直接使用@Autowired注解实现依赖注入,调用的时候直接报null异常。这是spring容器的初始化顺序造成的。解决方法如下:

1、使用工具类直接获取bean

这个方案非常简单,直接新建一个工具类,然后在需要的位置调用get方法获取想要的bean即可。

package com.example.demo.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}

2、使用@PostConstruct注解

使用@PostConstruct注解一个init方法来完成初始化,该方法会在bean注入完成后被自动调用,执行顺序为:构造函数 >> @Autowired >> @PostConstruct。

当前是一个抽象类,在其中使用@Autowired注入了消息中间件的相关依赖,然后使用@PostConstruct注解init方法实现后置处理器。

public abstract class AbsCommonBsHandler implements AbsCommonBsHandlerIntf {

	protected static AbsCommonBsHandler absCommonBsHandler;

	@Autowired
	public JmsMessagingTemplate messagingTemplate;
	@Autowired
	public Queue queue;
	@Autowired
	public Topic topic;

	@PostConstruct
	public void init() {
		absCommonBsHandler = this;
	}
	
	// 此处省略255个字符
	................................
}

当前使用子类继承上面的AbsCommonBsHandler抽象类,并用@Component注解注册为组件。

关键语句:

absCommonBsHandler.messagingTemplate.convertAndSend(absCommonBsHandler.queue, msg);
@Component
public class JJTSTReqHandler extends AbsCommonBsHandler {

	/**
	 * 处理消息
	 */
	@Override
	public void handler(SPPacket packet, String bsBody, ChannelContext channelContext) throws Exception {
		// 此处省略很多字符
		................................

		// 将接收到的消息送入队列
		absCommonBsHandler.messagingTemplate.convertAndSend(absCommonBsHandler.queue, msg);
	}
}

这样就能在handler中正常调用注入的bean了。正常操作不需要抽象类,恰好项目中有这一段,所以直接copy了。

发布了82 篇原创文章 · 获赞 9 · 访问量 6160

猜你喜欢

转载自blog.csdn.net/weixin_43424932/article/details/105436826