报错情况
今天在使用netty的自定义handler时,使用@autowire的service服务往数据库中读写数据时一直在报错空指针,debug发现所有应该被autowire的bean都是null,造成这种错误的原因是在此之前使用自动注入多数是在springIOC容器管理的bean中使用@Autowire或者@Resource注入,但是netty在编写启用的时候并没有托管给IOC容器。
解决方法
解决方法一:
使用@Component
和@PostConstruct
注解,给需要注入bean的handler类上加上Component注解,注册为spring的组件,同时增加一个方法
1 2 3 4 5 6 7
| public static MyHandler myHandler;
@PostConstruct public void init(){ myHandler=this; }
|
然后就可以正常使用@Autowire注解注入spring的bean了。
我在代码中使用的是第二种方法
解决方法二:
既然没有办法使用注解自动注入,那么我们就自己通过SpringUtil来获取需要的bean,在类加载的时候将其注入Handler中。
SpringUtil工具类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| 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 = null;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; }
}
public static ApplicationContext getApplicationContext() { return applicationContext; }
public static Object getBean(String name) { return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); }
public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); }
}
|
Handler中的具体使用:
1 2 3 4 5 6
| private static RestTemplate restTemplate; private static DiscoveryClient discoveryClient; static { restTemplate=SpringUtil.getBean(RestTemplate.class); discoveryClient=SpringUtil.getBean(DiscoveryClient.class); }
|
需要注意因为需要在类加载的时候就进行注入,所以使用static静态代码块,因为在静态代码块中需要调用,所以这两个成员也必须声明为静态变量。这样就可以不适用@Conponent和@Autowire以及@PostConstruct注解了。