方法一
第一步:写注解@Component 使当前类成为一个bean对象。(@Controller,@service都行)
第二步:写个static的变量
第三步:写个@PostConstruct注解注解注释的方法,在这个方法里,将自动注入的值赋值给定义的static变量
第四步:static变量替代自动注入在static方法里面使用
@Component
public class DSHWechatApiUtil extends DSHBaseController {
@Autowired
private IThirdPartyAuthDao thirdPartyAuthDao;
@Autowired
private static IThirdPartyAuthDao staticThirdPartyAuthDao;
@PostConstruct
public void init() {
staticThirdPartyAuthDao = thirdPartyAuthDao;
}
public static JSONObject getAuthorizerToken(String componentAccessToken, String authorizerAppid, String authorizerRefreshToken) {
JSONObject returnObject = new JSONObject();
try {
if (DSHUtils.isEmpty(componentAccessToken)) {
componentAccessToken = staticThirdPartyAuthDao.selectWechatValue(DSHConstants.WECHAT_PARAMS.COMPONENT_ACCESS_TOKEN);
}
} catch (Exception e) {
e.printStackTrace();
}
return returnObject;
}
}
@PostConstruct注解作用:是Java EE 5引入的注解,Spring允许开发者在受管Bean中使用它。当DI容器实例化当前受管Bean时,@PostConstruct注解的方法会被自动触发,从而完成一些初始化工作。
注意:
- 只有一个方法可以使用此注释进行注解;
- 被注解方法不得有任何参数;
- 被注解方法返回值为void;
- 被注解方法不得抛出已检查异常;
- 被注解方法需是非静态方法;
- 此方法只会被执行一次;
方法二
将@Autowire加到构造方法上
@Component
public class Test {
private static UserService userService;
@Autowired
public Test(UserService userService) {
Test.userService = userService;
}
public static void test() {
userService.test();
}
}
发生的场景
好几次有个同事因为把static用到Spring的@Autowired上,导致注入的对象一直报空指针,他一直找不到错误在哪里,来问我,其实我以前也不知道这个问题,但我根据Spring容器的特点判定,他调用的对象与注入的对象不是一个对象,就告诉他:static的加载顺序是在@Autowired之前;之后查资料才知道其实不是这样。。。
原理剖析
静态变量、类变量不是对象的属性,而是一个类的属性,所以静态方法是属于类(class)的,普通方法才是属于实体对象(也就是New出来的对象)的,spring注入是在容器中实例化对象,所以不能使用静态方法。而使用静态变量、类变量扩大了静态方法的使用范围。静态方法在spring是不推荐使用的,依赖注入的主要目的,是让容器去产生一个对象的实例,然后在整个生命周期中使用他们,同时也让testing工作更加容易。一旦你使用静态方法,就不再需要去产生这个类的实例,这会让testing变得更加困难,同时你也不能为一个给定的类,依靠注入方式去产生多个具有不同的依赖环境的实例,这种static field是隐含共享的,并且是一种global全局状态,Spring同样不推荐这样去做。