網上已經有大把文章介紹bean的生命週期和執行順序,但是都是針對單個bean的。
今天在項目遇到一個問題:A類實現了BeanFactoryAware接口,將BeanBeanFactory對象保存在自己的static變量中。
public class A implements BeanFactoryAware {
private static BeanFactory beanFactory;
public static BeanFactory getBeanFactory() {
return beanFactory;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("aaa");
A.beanFactory = beanFactory;
}
}
B類實現了InitializingBean接口,希望獲取到BeanBeanFactory對象。
public class B implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("bbbb");
System.out.println(A.getBeanFactory()==null);
}
}
現在我們來測試下着2個方法的執行順序:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="net.aty.spring.A"></bean>
<bean class="net.aty.spring.B"></bean>
</beans>
public class MainTst {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring.xml");// 加載 spring 配置文件
}
}
程序輸出如下:
現在我們修改下xml文件,測試java代碼不變:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="net.aty.spring.B"></bean>
<bean class="net.aty.spring.A"></bean>
</beans>
我們項目恰好使用的是第二種方式,結果就導致空指針了。對於單個bean來說,確實是先執行BeanFactoryAware,後執行InitializingBean。但是對於不同的bean來說,並沒有這個順序保證。上面測試可以看出:先定義的bean先執行。
spring判斷bean的依賴關係,無非就是構造注入和set注入,上面的2個A和B並沒有顯示地依賴關係,雖然邏輯上是B依賴於A,但是spring並不知道這種關係。爲了讓spring知道這種邏輯上的依賴關係,spring專門提供了depends-on。