banner
NEWS LETTER

Netty使用Handler时使用@Autowire注解注入的bean为null解决方法

Scroll down

报错情况

今天在使用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;
}

}


/**
* 获取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);
}

}

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注解了。

其他文章