欢迎来到代码驿站!

JAVA代码

当前位置:首页 > 软件编程 > JAVA代码

详谈@Autowired和static的关系

时间:2021-11-17 13:17:42|栏目:JAVA代码|点击:

@Autowired和static的关系

一、发生的场景

好几次有个同事因为把static用到Spring的@Autowired上,导致注入的对象一直报空指针,他一直找不到错误在哪里,来问我,其实我以前也不知道这个问题,但我根据Spring容器的特点判定,他调用的对象与注入的对象不是一个对象,就告诉他:static的加载顺序是在@Autowired之前;之后查资料才知道其实不是这样。。。

二、原理剖析  

静态变量、类变量不是对象的属性,而是一个类的属性,所以静态方法是属于类(class)的,普通方法才是属于实体对象(也就是New出来的对象)的,spring注入是在容器中实例化对象,所以不能使用静态方法。

而使用静态变量、类变量扩大了静态方法的使用范围。静态方法在spring是不推荐使用的,依赖注入的主要目的,是让容器去产生一个对象的实例,然后在整个生命周期中使用他们,同时也让testing工作更加容易。

一旦你使用静态方法,就不再需要去产生这个类的实例,这会让testing变得更加困难,同时你也不能为一个给定的类,依靠注入方式去产生多个具有不同的依赖环境的实例,这种static field是隐含共享的,并且是一种global全局状态,Spring同样不推荐这样去做。

三、解决方案

1、将@Autowire加到构造方法上

@Component
public class Test {    
    private static UserService userService;    
    @Autowired
    public Test(UserService userService) {
        Test.userService = userService;
    }    
    public static void test() {
        userService.test();
    }
}

2、用@PostConstruct注解

@Component
public class Test {    
    private static UserService userService;    
    @Autowired
    private UserService userService2;    
    @PostConstruct
    public void beforeInit() {
        userService = userService2;
    }    
    public static void test() {
        userService.test();
    }
}

static方法使用@Autowired

set注入失败 构造器注入成功

@Component
@Slf4j
public class UserCookieInfoUtil {
    private static RedisTemplate<String, String> redisTemplate;
    private static JWTUtils jwtUtils;
    @Autowired
    public UserCookieInfoUtil(JWTUtils jwtUtils, RedisTemplate<String, String> redisTemplate) {
        UserCookieInfoUtil.jwtUtils = jwtUtils;
        UserCookieInfoUtil.redisTemplate = redisTemplate;
    }
    public static Map<String, Object> getCookieInfo(String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            String loginName = jwtUtils.getLoginName(token);
            String info = redisTemplate.opsForValue().get(Constants.TOKEN_USER_INFO + ":" + loginName);
            map = JSONObject.parseObject(info == null ? "" : info, Map.class);
        } catch (Exception e){
            log.error("获取缓存中的登录信息失败:{}", e);
        }
        return map;
    }
}

上一篇:Java并发之Condition案例详解

栏    目:JAVA代码

下一篇:Mybatis调用视图和存储过程的方法

本文标题:详谈@Autowired和static的关系

本文地址:http://www.codeinn.net/misctech/183823.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有