详谈@Autowired和static的关系

 更新时间:2021年08月26日 14:22:20   作者:左手程序,右手诗  
这篇文章主要介绍了@Autowired和static的关系,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@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类型通配符应用实战分析

    Java类型通配符应用实战分析

    这篇文章主要介绍了Java类型通配符应用实战,简单分析了Java类型通配符概念、原理并结合实例形式给出了Java类型通配符相关使用技巧,需要的朋友可以参考下
    2019-07-07
  • 解决springboot配置文件组解决自动配置属性无法注入问题

    解决springboot配置文件组解决自动配置属性无法注入问题

    在使用Spring Boot时,可能会遇到配置文件属性注入失败的问题,本文描述了一个案例,其中尝试使用profile文件组指定不同环境下的配置文件,但遇到了属性无法成功注入的情况,提供的解决办法是将Spring Boot的版本号从2.2.0.RELEASE升级到2.4.0
    2024-09-09
  • kafka并发写大消息异常TimeoutException排查记录

    kafka并发写大消息异常TimeoutException排查记录

    这篇文章主要为大家介绍了kafka并发写大消息异常TimeoutException的排查记录及解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • 详解Java中Vector和ArrayList的区别

    详解Java中Vector和ArrayList的区别

    这篇文章主要为大家详细介绍了Java中Vector和ArrayList的区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • java mybatis框架配置详解

    java mybatis框架配置详解

    在本篇文章里小编给大家整理的是一篇关于java mybatis框架配置详解内容,对此有兴趣的朋友们可以参考下。
    2021-02-02
  • Java框架篇:Spring+SpringMVC+hibernate整合开发

    Java框架篇:Spring+SpringMVC+hibernate整合开发

    本篇文章将会对Spring+SpringMVC+hibernate的整合开发进行介绍。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-02-02
  • WebService的相关概念

    WebService的相关概念

    这篇文章主要介绍了WebService的相关概念的相关资料,需要的朋友可以参考下
    2017-10-10
  • 用java开发dota英雄最华丽的技能(实例讲解)

    用java开发dota英雄最华丽的技能(实例讲解)

    下面小编就为大家分享一篇使用java开发dota英雄最华丽的技能实例,具有非常好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • Java通过cellstyle属性设置Excel单元格常用样式的全面总结讲解

    Java通过cellstyle属性设置Excel单元格常用样式的全面总结讲解

    在处理Excel文件时,经常需要对单元格进行样式设置,以满足特定的需求和美化要求,这篇文章主要给大家介绍了关于Java通过cellstyle属性设置Excel单元格常用样式的相关资料,需要的朋友可以参考下
    2024-01-01
  • Java中EasyPoi导出复杂合并单元格的方法

    Java中EasyPoi导出复杂合并单元格的方法

    这篇文章主要介绍了Java中EasyPoi导出复杂合并单元格的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论