原因:
netty 中无法使用注入的bean,因为NettyClientHandler 是netty启动的时候new出来,并没有交给spring IOC托管,后面给NettyClientHandler 加上@Component 注解也不行,因为netty 的加载优于spring容器初始化,
解决方案1:
想在生成对象时完成某些初始化操作,而这些初始化操作又依赖于注入的bean,因此可以使用@PostConstruct注解一个init方法来完成初始化,该方法会在bean注入完成后被自动调用。
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
@Resource
private RedissonUtils redissonUtils;
private static NettyClientHandler nettyClientHandler ;
@PostConstruct
public void init() {
nettyClientHandler = this;
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
nettyClientHandler.redissonUtils.getString()
}
}
解决方案2:
使用工具类来获取需要的bean, 实现ApplicationContextAware 接口
@Component
@Slf4j
public class SpringBootBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringBootBeanUtil.applicationContext == null) {
SpringBootBeanUtil.applicationContext = applicationContext;
}
log.debug("========ApplicationContext配置成功========");
log.debug("========在普通类可以通过调用SpringBootBeanUtil.getApplicationContext()获取applicationContext对象========");
log.debug("========applicationContext=" + SpringBootBeanUtil.applicationContext + "========");
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}