SpringBoot之@Autowired和static静态资源的那些事Spring中@Autowired注解和静态⽅法关联应⽤
背景:
static修饰的成员(包括变量和⽅法)叫静态成员,都存放在⽅法区中的静态区,随着类的加载⽽存在、类的回收⽽释放,和对象存在与否没有关系,并且要先于对象存在。(所以导致static修饰的⽅法,⾥⾯的东西不要依赖于其他实例化对象,依赖的话就会出现空指针异常。所以这个问题如何避免,就需要改进)
⼀、业务场景
⾸先我们的类对象在创建⽅法的时候如果使⽤static进⾏修饰,那么就可以实现可以在外部进⾏调⽤。
如下所⽰如果没有static修饰,外部将不能使⽤该⽅法:
public class GetToken {
static修饰的变量public static String Signature(String access_token, String timestamp) {
//下⾯的"& timestamp"之间没有空格,由于⽂本转译原因这⾥需要加空格
String hashStr = "access_token=" + access_token + "& timestamp=" + timestamp;
//进⾏SHA1加密后⽣成signature
return SHA1(hashStr);
}
}
@Test
void test6() {
System.out.println("测试static修饰函数的");
String str = GetToken.Signature("1234", "2345");
System.out.println(str);
}
⼆.理论原理:
spring框架应⽤中有些静态⽅法需要依赖被容器管理的类,就像这样:
@Component
public class Test {
@Autowired
private static UserService userService;
public static void test() {
}
}
这样⼀定会报java.lang.NullPointerException: null异常。
⼆、原理剖析
静态变量、类变量不是对象的属性,⽽是⼀个类的属性,所以静态⽅法是属于类(class)的,普通⽅法才是属于实体对象(也就是New出来的对象)的,spring注⼊是在容器中实例化对象,所以不能使⽤静态⽅法。
⽽使⽤静态变量、类变量扩⼤了静态⽅法的使⽤范围。静态⽅法在spring是不推荐使⽤的,依赖注⼊的主要⽬的,是让容器去产⽣⼀个对象的实例,然后在整个⽣命周期中使⽤他们,同时也让testing⼯作更加容易。
⼀旦你使⽤静态⽅法,就不再需要去产⽣这个类的实例,这会让testing变得更加困难,同时你也不能为⼀个给定的类,依靠注⼊⽅式去产⽣多个具有不同的依赖环境的实例,这种static field是隐含共享的,并且是⼀种global全局状态,spring同样不推荐这样去做。
在Springframework⾥,我们是不能@Autowired⼀个静态变量,使之成为⼀个Spring bean的。为什么?其实很简单,因为当类加载器加载静态变量时,Spring上下⽂尚未加载。所以类加载器不会在bean中正确注⼊静态类,并且会失败。
三、解决⽅法
1、将@Autowire加到构造⽅法上
@Component
public class Test {
private static UserService userService;
@Autowired
public Test(UserService userService) {
Test.userService = userService;
}
public static void 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() {
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论