详谈@Autowired和static的关系
作者:左手程序,右手诗 发布时间:2022-06-14 05:51:50
标签:@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;
}
}
来源:https://www.cnblogs.com/pangyangqi/p/10010866.html
0
投稿
猜你喜欢
- 简介MapStruct 是一个代码生成器(可以生成对象映射转换的代码),它基于约定优于配置的方法,极大地简化了 Java bean 类型之间
- JNI简介JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C
- 概念 在 HTML 中,<a>, <form>, <img>, <script>,
- 1. 什么是AOPAOP (Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期 * 实现在
- 昨天下午快下班的时候,无意中听到公司两位同事在探讨批量向数据库插入数据的性能优化问题,顿时来了兴趣,把自己的想法向两位同事说了一下,于是有了
- SpringBoot使用Commons Logging进行所有内部日志记录,但保留底层日志实现。默认提供了Java Util Logging
- 日常的Rest服务开发我都会首选SpringBoot,因为它本身的易用性以及自带的各种方便功能、生态等,今天就简单讲一下如何将Spring
- tjxCold(根据配置模板,快速生成controller,service,serviceimpl 代码) 为什么要开发这款插件市面上有很多
- JAVA中的类只能是public 或者package的。这是符合逻辑的:人们定义类的初衷就是为了让别人用的。倘若是private,别人怎么调
- Java数组的定义和使用如果希望保存一组有相同类型的数据,可以使用数组。数组的定义和内存分配Java 中定义数组的语法有两种:
- 熟悉Eclipse的都知道Eclipse经常性的会出现一些莫名其妙的问题,有时候运行的好好的突然重启一下项目就莫名的报错,所以经常会用到cl
- 在使用IDEA写代码的时候,打开tabs都挤在一行,当打开页面过多的时候,前面的页面无法直观看到,非常不方便。通过简单设置就可以实现tabs
- Intellij IDEA 最突出的功能自然是调试(Debug),可以对Java代码,JavaScript,JQuery,Ajax等技术进行
- 一、使用JDK生成WSDL的对象类1、cmd进入JDK的bin文件中执行命令 wsimport -keep -p com.demo.clie
- 1.简介建议阅读本文最好对Dokcer有一些了解首先我们先了解一下Docker是什么Docker 属于 Linux 容器的一种封装,提供简单
- 1.属性驱动 前台表单中字段的name和后台action中的属性字段的名称必须保持一致;2.域驱动 前台表单中字段的name应该为:obje
- Web Fragment 是什么 - 它是在 servlet 3.0开始支持的,可以把一个dy web项目拆分为多个项目,解耦合,使其在项目
- springboot项目还是ssm等java常用框架都会有这样的问题,解决办法通用问题场景前端发送Post请求,前端返回400 Bad Re
- C#延时函数sleepsleepusing System.Threading; //导入命名空间,类Thread就在此空间中Th
- 话不多说直接上代码,简单明了import java.io.File;import java.io.FileInputStream;impor