經過一個簡單的Maven工程來演示Spring的Bean生命週期函數的執行順序.java
下面是工程的目錄結構:spring
直接貼代碼:apache
pom.xml文件內容:maven
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.xuebusi</groupId> 8 <artifactId>spring-test</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <dependencies> 12 <dependency> 13 <groupId>org.springframework</groupId> 14 <artifactId>spring-context</artifactId> 15 <version>4.3.12.RELEASE</version> 16 </dependency> 17 18 <dependency> 19 <groupId>junit</groupId> 20 <artifactId>junit</artifactId> 21 <version>4.12</version> 22 <scope>test</scope> 23 </dependency> 24 </dependencies> 25 26 </project>
beans.xml配置文件:ide
該配置文件主要用於演示init-method和destory-method兩個方法的執行時機.函數
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 6 7 <context:component-scan base-package="com.xuebusi"></context:component-scan> 8 <bean id="userService" class="com.xuebusi.service.UserService" init-method="init" destroy-method="destory"/> 9 </beans>
SpringBeanPostProcessor類:post
這個類繼承了InstantiationAwareBeanPostProcessorAdapter類,重寫了它的一些和Bean的實例化以及初始化有關的生命週期方法.測試
可是這些方法是針對Spring容器中的全部Bean的,因此加了個if判斷,由於這裏只是演示userService這個Bean的生命週期.this
1 import org.springframework.beans.BeansException; 2 import org.springframework.beans.PropertyValues; 3 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; 4 import org.springframework.stereotype.Component; 5 6 import java.beans.PropertyDescriptor; 7 8 @Component 9 public class SpringBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { 10 11 @Override 12 public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 13 if ("userService".equals(beanName)) { 14 System.out.println(">>>> postProcessBeforeInstantiation"); 15 } 16 return super.postProcessBeforeInstantiation(beanClass, beanName); 17 } 18 19 @Override 20 public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 21 if ("userService".equals(beanName)) { 22 System.out.println(">>>> postProcessAfterInstantiation"); 23 } 24 return super.postProcessAfterInstantiation(bean, beanName); 25 } 26 27 @Override 28 public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { 29 if ("userService".equals(beanName)) { 30 System.out.println(">>>> postProcessPropertyValues"); 31 } 32 return super.postProcessPropertyValues(pvs, pds, bean, beanName); 33 } 34 35 @Override 36 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 37 if ("userService".equals(beanName)) { 38 System.out.println(">>>> postProcessBeforeInitialization"); 39 } 40 return super.postProcessBeforeInitialization(bean, beanName); 41 } 42 43 @Override 44 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 45 if ("userService".equals(beanName)) { 46 System.out.println(">>>> postProcessAfterInitialization"); 47 } 48 return super.postProcessAfterInitialization(bean, beanName); 49 } 50 }
UserService類:spa
這就是要演示的Bean,讓它實現Spring的InitializingBean接口來測試afterPropertiesSet方法, 實現BeanNameAware接口來測試setBeanName方法,實現BeanFactoryAware接口來測試setBeanFactory方法.
1 import org.springframework.beans.BeansException; 2 import org.springframework.beans.factory.BeanFactory; 3 import org.springframework.beans.factory.BeanFactoryAware; 4 import org.springframework.beans.factory.BeanNameAware; 5 import org.springframework.beans.factory.InitializingBean; 6 import org.springframework.stereotype.Service; 7 8 import javax.annotation.PostConstruct; 9 import javax.annotation.PreDestroy; 10 11 @Service 12 public class UserService implements InitializingBean, BeanNameAware, BeanFactoryAware { 13 14 private String userName; 15 16 public UserService() { 17 System.out.println(">>>> UserService"); 18 } 19 20 public String getUserName() { 21 return userName; 22 } 23 24 public void setUserName(String userName) { 25 this.userName = userName; 26 } 27 28 @PostConstruct 29 public void postConstruct() { 30 System.out.println(">>>> postConstruct"); 31 } 32 33 @PreDestroy 34 public void preDestroy() { 35 System.out.println(">>>> preDestroy"); 36 } 37 38 public void init() { 39 System.out.println(">>>> init"); 40 } 41 42 public void destory() { 43 System.out.println(">>>> destory"); 44 } 45 46 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 47 System.out.println(">>>> setBeanFactory"); 48 } 49 50 public void setBeanName(String s) { 51 System.out.println(">>>> setBeanName"); 52 } 53 54 public void afterPropertiesSet() throws Exception { 55 System.out.println(">>>> afterPropertiesSet"); 56 } 57 }
AppTest類:
該類經過junit測試方法來啓動一個Spring容器,並從容器中獲取userService這個Bean對象.最後調用close方法銷燬Spring容器.
1 import com.xuebusi.service.UserService; 2 import org.junit.Test; 3 import org.springframework.context.support.ClassPathXmlApplicationContext; 4 5 public class AppTest { 6 7 @Test 8 public void run() { 9 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 10 UserService userService = context.getBean("userService", UserService.class); 11 userService.setUserName("蒼井空"); 12 String userName = userService.getUserName(); 13 System.out.println(userName); 14 context.close(); 15 } 16 }
運行AppTest的測試方法run()而後觀察控制檯,日誌展現出了"userService"這個Bean的生命週期函數執行順序:
1 >>>> postProcessBeforeInstantiation 2 >>>> UserService 3 >>>> postProcessAfterInstantiation 4 >>>> postProcessPropertyValues 5 >>>> setBeanName 6 >>>> setBeanFactory 7 >>>> postProcessBeforeInitialization 8 >>>> postConstruct 9 >>>> afterPropertiesSet 10 >>>> init 11 >>>> postProcessAfterInitialization 12 蒼井空 13 >>>> preDestroy 14 >>>> destory
總結一個Bean的生命週期方法執行順序:
1. 實例化前 postProcessBeforeInstantiation() 2. 構造方法 構造方法 3. 實例化後 postProcessAfterInstantiation() 4. 設置屬性 postProcessProperties() 5. 設置Bean名稱 setBeanName() 6. 設置BeanFactory setBeanFactory() 7. 初始化前 postProcessBeforeInitialization() 8. 構造以後 加了 @PostConstruct 的方法 9. 全部屬性賦值以後 afterPropertiesSet() 10.初始化方法 配置文件中指定的 init-method 方法 10.初始化後 postProcessAfterInitialization() 11.銷燬以前 加了 @PreDestroy 的方法 12.銷燬方法 配置文件中指定的 destroy-method 方法