1.简述
目前所有的java项目,都会使用spring框架,spring主要核心功能就是ioc和aop,ioc是依赖注入和控制反转,aop是面向切面编程,今天不会详细讲解ioc和aop,主要核心内容就是如何将spring管理的bean,注入的静态方法。
2.会出现的问题
如果我们使用正常的@Component注解将一个类交由spring管理,然后在使用的时候用@Resource注入对象,在没有碰到静态方法的时候,是不会出现问题,但是如果出现了静态方法,这样的使用方法就会出现空指针的异常,也就是你@Resource注入的对象是空
3.为什么会出现这种情况
首先我和大家先说一下static关键字的作用,如果一个方法或者变量被static修饰,则说明改方法或者变量就成为了类方法或者变量,随着类的加载而加载,会被当前类下的所有对象所共有
其次我在简单说一下@Resource的作用,就是去springbean工厂中去匹配一个对象,并且完成对象的注入,这属于对象级别的,在此时,类的所有静态属性已经被加载完成
经过上面的解释,我相信大家已经知道什么原因了,那就是类加载的先后顺序导致的,静态属性会在程序第一次启动的时候,就完成加载,并且之后不会再有变动,但是使用@Resource注解,则是每次都去spring容器去获取bean,在静态变量初始化的后面,所有就会导致@Resource出现空的情况
4.怎么解决这种问题
今天我在这里只说一种解决方案,那就是通过定义静态的成员变量,已经使用spring自带的@PostConstruct对spring bean进行初始化,简单和大家说一下@PostConstruct的作用,就是在构造方法执行完成后需要执行的代码,可能我说的比较抽象,下面上代码,大家看了就知道如何解决了
5.代码内容
- 错误使用方式
@Component
public class TestStaticUtil {
@Autowired
private static TestSpringBean testSpringBean;
public static void testSpring(){
testSpringBean.hello();
}
}
2.正确的使用方式
@Component
public class TestStaticUtil {
@Autowired
private TestSpringBean testSpringBean;
private static TestStaticUtil testStaticUtil;
@PostConstruct
public void init(){
testStaticUtil = this;
testStaticUtil.testSpringBean = this.testSpringBean;
}
public static void testSpring(){
testStaticUtil.testSpringBean.hello();
}
}