详谈@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; } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Spring cloud如何实现FeignClient指定Zone调用
这篇文章主要介绍了Spring cloud如何实现FeignClient指定Zone调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03Spring Data JPA中的Specification动态查询详解
Specification是一个设计模式,用于企业级应用开发中,其主要目的是将业务规则从业务逻辑中分离出来,在数据查询方面,Specification可以定义复杂的查询,使其更易于重用和测试,这篇文章主要介绍了Spring Data JPA中的Specification动态查询详解,需要的朋友可以参考下2023-07-07idea配置全局变量Jdk、maven仓库以及maven详解(全文图解)
这篇文章主要给大家介绍了关于idea配置全局变量Jdk、maven仓库以及maven的相关资料,在配置JDK和Maven之前,需要确保已经正确安装了JDK和Maven,文中通过图文介绍的非常详细,需要的朋友可以参考下2024-01-01
最新评论