先來一個Demo,然后再來進行源碼分析:
一、示例
1.創建一個Bean,並實現一些XxxAware 接口
public class Book implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String bookName; public Book() { System.out.println("bean實例化 "); } public void setBookName(String bookName) { this.bookName = bookName; System.out.println("設置屬性值"); } public String getBookName() { return bookName; } // 實現 BeanNameAware 的方法 @Override public void setBeanName(String name) { System.out.println("調用 BeanNameAware 的 setBeanName 方法"); } // 實現 BeanFactoryAware 的方法 @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("調用 BeanFactoryAware 的 setBeanFactory 方法"); } // 實現 ApplicationContextAware 的方法 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("調用 ApplicationContextAware 的 setApplicationContext 方法"); } // 自定義初始化方法 @PostConstruct public void springPostConstruct() { System.out.println("@PostConstruct"); } // 實現 InitializingBean 的方法 @Override public void afterPropertiesSet() throws Exception { System.out.println("調用 InitializingBean 的 afterPropertiesSet 方法"); } // init-method public void myPostConstruct() { System.out.println("調用 init-method 屬性配置的初始化方法"); } // 自定義銷毀方法 @PreDestroy public void springPreDestory() { System.out.println("@PreDestory"); } // 實現 DisposableBean @Override public void destroy() throws Exception { System.out.println("調用 DisposableBean 的 destroy 方法"); } // destroy-method public void myPreDestory() { System.out.println("調用 destroy-method 屬性配置的銷毀方法"); System.out.println("---------------destroy-----------------"); } @Override protected void finalize() throws Throwable { System.out.println("------inside finalize-----"); } }
2.自定義一個 BeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Book) { System.out.println("調用 BeanPostProcessor 的預初始化方法"); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Book) { System.out.println("調用 BeanPostProcessor 的后初始化方法"); } return bean; } }
3.bean-lifecycle.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 掃描bean --> <context:component-scan base-package="com.lifecycle" /> <!-- 實現了用戶自定義初始化和銷毀方法 --> <bean id="book" class="com.lifecycle.Book" init-method="myPostConstruct" destroy-method="myPreDestory"> <!-- 注入bean 屬性名稱 --> <property name="bookName" value="《thingking in java》" /> </bean> <!--引入自定義的BeanPostProcessor --> <bean class="com.lifecycle.MyBeanPostProcessor" /> </beans>
4.測試
public class SpringBeanLifecycleApplication { public static void main(String[] args) throws InterruptedException { ApplicationContext context = new ClassPathXmlApplicationContext("bean-lifecycle.xml"); Book book = (Book) context.getBean("book"); System.out.println("開始使用bean:book.bookName = " + book.getBookName()); ((ClassPathXmlApplicationContext) context).destroy(); } }
打印結果:
bean實例化 設置屬性值 調用 BeanNameAware 的 setBeanName 方法 調用 BeanFactoryAware 的 setBeanFactory 方法 調用 ApplicationContextAware 的 setApplicationContext 方法 調用 BeanPostProcessor 的預初始化方法 @PostConstruct 調用 InitializingBean 的 afterPropertiesSet 方法 調用 init-method 屬性配置的初始化方法 調用 BeanPostProcessor 的后初始化方法 開始使用bean:book.bookName = 《thingking in java》 @PreDestory 調用 DisposableBean 的 destroy 方法 調用 destroy-method 屬性配置的銷毀方法 ---------------destroy-----------------
Bean的生命周期總結如圖
二、完成的示例
接下來我們再來看一個完成版的Bean生命周期
1.創建一個子類,繼承Book類,並實現一些XxxAware類
public class SubBookClass extends Book implements BeanClassLoaderAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware { private String bookSystem; public SubBookClass() { super(); System.out.println("子類:bean實例化 "); } public String getBookSystem() { return bookSystem; } public void setBookSystem(String bookSystem) { System.out.println("子類:設置屬性值"); this.bookSystem = bookSystem; } // 實現 BeanClassLoaderAware 的方法 public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("子類:調用 BeanClassLoaderAware 的 setBeanClassLoader 方法"); } // 實現 ApplicationEventPublisherAware 的方法 public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("子類:調用 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法"); } // 實現 EmbeddedValueResolverAware 的方法 public void setEmbeddedValueResolver(StringValueResolver resolver) { System.out.println("子類:調用 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法"); } // 實現 EnvironmentAware 的方法 public void setEnvironment(Environment environment) { System.out.println("子類:調用 EnvironmentAware 的 setEnvironment 方法"); } // 實現 MessageSourceAware 的方法 public void setMessageSource(MessageSource messageSource) { System.out.println("子類:調用 MessageSourceAware 的 setMessageSource 方法"); } // 實現 ResourceLoaderAware 的方法 public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("子類:調用 ResourceLoaderAware 的 setResourceLoader 方法"); } }
2.sub-bean-lifecycle.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="bookClass" class="com.lifecycle.SubBookClass" init-method="myPostConstruct" destroy-method="myPreDestory"> <property name="bookSystem" value="Java System" /> </bean> <bean class="com.lifecycle.MyBeanPostProcessor" /> </beans>
3.測試
public class SpringBeanLifecycleApplication { public static void main(String[] args) throws InterruptedException { // 為面試而准備的Bean生命周期加載過程 ApplicationContext context = new ClassPathXmlApplicationContext("bean-lifecycle.xml"); Book book = (Book) context.getBean("book"); System.out.println("開始使用bean:book.bookName = " + book.getBookName()); ((ClassPathXmlApplicationContext) context).destroy(); System.out.println("\r\n"); // 完整的加載過程,當然了解的越多越好 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("sub-bean-lifecycle.xml"); SubBookClass subBookClass = (SubBookClass) applicationContext.getBean("bookClass"); System.out.println("BookSystemName = " + subBookClass.getBookSystem()); ((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook(); } }
打印結果:
bean實例化 :com.lifecycle2.Book@22eeefeb 設置屬性值:bookName《thingking in java》 調用 BeanNameAware 的 setBeanName 方法 book 調用 BeanFactoryAware 的 setBeanFactory 方法 調用 ApplicationContextAware 的 setApplicationContext 方法 調用 BeanPostProcessor 的預初始化方法 @PostConstruct 調用 InitializingBean 的 afterPropertiesSet 方法 調用 init-method 屬性配置的初始化方法 調用 BeanPostProcessor 的后初始化方法 開始使用bean:book.bookName = 《thingking in java》 @PreDestory 調用 DisposableBean 的 destroy 方法 調用 destroy-method 屬性配置的銷毀方法 ---------------destroy----------------- bean實例化 :com.lifecycle2.SubBookClass@27fe3806 子類:bean實例化 子類:設置屬性值 調用 BeanNameAware 的 setBeanName 方法 bookClass 子類:調用 BeanClassLoaderAware 的 setBeanClassLoader 方法 調用 BeanFactoryAware 的 setBeanFactory 方法 子類:調用 EnvironmentAware 的 setEnvironment 方法 子類:調用 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法 子類:調用 ResourceLoaderAware 的 setResourceLoader 方法 子類:調用 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法 子類:調用 MessageSourceAware 的 setMessageSource 方法 調用 ApplicationContextAware 的 setApplicationContext 方法 調用 BeanPostProcessor 的預初始化方法 調用 InitializingBean 的 afterPropertiesSet 方法 調用 init-method 屬性配置的初始化方法 調用 BeanPostProcessor 的后初始化方法 BookSystemName = Java System 調用 DisposableBean 的 destroy 方法 調用 destroy-method 屬性配置的銷毀方法 ---------------destroy-----------------
- 創建Bean:加載配置的時候
- 使用Bean
- 銷毀Bean:調用 destroy 方法的時候
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 1.實例化bean instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // 省略部分代碼 ... // Initialize the bean instance. Object exposedObject = bean; try { // 2.屬性賦值 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 3.初始化bean exposedObject = initializeBean(beanName, exposedObject, mbd); } } // 省略部分代碼 ... return exposedObject; }
通過doCreateBean 方法,我們知道創建Bean大概有3大步驟:
實例化 bean
屬性注入
初始化 bean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { // 3.1 調用實現XxxAware類的方法 invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { // 3.1 調用Aware的方法 // 3.1 調用 BeanNameAware 的 setBeanName 方法 // 3.1 調用 BeanClassLoaderAware 的 setBeanClassLoader // 3.1 調用 BeanFactoryAware 的 setBeanFactory 方法 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 3.2 執行 BeanPostProcessor 的預初始化方法 // 3.2 調用 EnvironmentAware 的 setEnvironment 方法 // 3.2 調用 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法 // 3.2 調用 ResourceLoaderAware 的 setResourceLoader 方法 // 3.2 調用 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法 // 3.2 調用 MessageSourceAware 的 setMessageSource 方法 // 3.2 調用 ApplicationContextAware 的 setApplicationContext 方法 // 3.2 調用 BeanPostProcessor 的預初始化方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 3.3 調用初始化方法 // (1)調用 InitializingBean 的 afterPropertiesSet 方法 // (2)調用 用戶定義的初始化方法,即init-method 屬性配置的方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 3.4 調用 BeanPostProcessor 的后初始化方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
通過initializeBean 方法,我們把初始化Bean大概有4大步驟:
調用實現XxxAware類的方法
執行 BeanPostProcessor 的預初始化方法
調用初始化方法
調用 BeanPostProcessor 的后初始化方法
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { // 如果實現 BeanNameAware 接口,則會調用 setBeanName 方法 if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } // 如果實現 BeanClassLoaderAware 接口,則會調用 setBeanClassLoader 方法 if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } // 如果實現 BeanFactoryAware 接口,則會調用 setBeanFactory 方法 if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
3.2 執行 BeanPostProcessor 的預初始化方法
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { // 這里首先會調用 ApplicationContextAwareProcessor 中的 postProcessBeforeInitialization方法 // 這里最后會調用 MyBeanPostProcessor 中的postProcessBeforeInitialization 方法 result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
ApplicationContextAwareProcessor 中的 postProcessBeforeInitialization方法如下:
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareInterfaces(bean); return null; } }, acc); } else { // 核心代碼: invokeAwareInterfaces(bean); } return bean; }
下面這段代碼就是判斷是否實現了XxxAware 接口,並調用相應的setXxx 方法
private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { // 如果實現了 EnvironmentAware 接口,則會調用 setEnvironment方法 if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } // 如果實現了 EmbeddedValueResolverAware 接口,則會調用 setEmbeddedValueResolver方法 if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } // 如果實現了 ResourceLoaderAware 接口,則會調用 setResourceLoader方法 if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } // 如果實現了 ApplicationEventPublisherAware 接口,則會調用 setApplicationEventPublisher方法 if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } // 如果實現了 MessageSourceAware 接口,則會調用 setMessageSource方法 if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } // 如果實現了 ApplicationContextAware 接口,則會調用 setApplicationContext方法 if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } }
3.3 調用初始化方法
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { // 調用 InitializingBean 的 afterPropertiesSet 方法 ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 調用 InitializingBean 的 afterPropertiesSet 方法 ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { // 調用 用戶定義的初始化方法,即init-method 屬性配置的方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
3.4 調用 BeanPostProcessor 的后初始化方法
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { // 這里就會調用 MyBeanPostProcessor 中的 postProcessAfterInitialization result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
根據源碼,總結spring bean的生命周期:
創建Bean:
1.實例化 bean
2.屬性注入
3.初始化 bean
3.1調用實現XxxAware類的方法
調用 BeanNameAware 的 setBeanName 方法
調用 BeanClassLoaderAware 的 setBeanClassLoader
調用 BeanFactoryAware 的 setBeanFactory 方法
3.2執行 BeanPostProcessor 的預初始化方法
調用 EnvironmentAware 的 setEnvironment 方法
調用 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法
調用 ResourceLoaderAware 的 setResourceLoader 方法
調用 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法
調用 MessageSourceAware 的 setMessageSource 方法
調用 ApplicationContextAware 的 setApplicationContext 方法
調用 BeanPostProcessor 的預初始化 postProcessBeforeInitialization方法
3.3調用初始化方法
調用 InitializingBean 的 afterPropertiesSet 方法
調用 用戶定義的初始化方法,即init-method 屬性配置的方法
3.4調用 BeanPostProcessor 的后初始化 postProcessAfterInitialization方法
銷毀Bean:
調用 @PreDestroy 注解的方法
調用 DisposableBean 的 destroy 方法
調用 destroy-method 屬性配置的銷毀方法
我們再看一下BeanFactory 源碼給出的解釋:
/* * * <p>Bean factory implementations should support the standard bean lifecycle interfaces * as far as possible. The full set of initialization methods and their standard order is: * 初始化方法執行的標准順序: * <ol> * <li>BeanNameAware's {@code setBeanName} * <li>BeanClassLoaderAware's {@code setBeanClassLoader} * <li>BeanFactoryAware's {@code setBeanFactory} * <li>EnvironmentAware's {@code setEnvironment} * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver} * <li>ResourceLoaderAware's {@code setResourceLoader} (only applicable when running in an application context) * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher} (only applicable when running in an application context) * <li>MessageSourceAware's {@code setMessageSource} (only applicable when running in an application context) * <li>ApplicationContextAware's {@code setApplicationContext} (only applicable when running in an application context) * <li>ServletContextAware's {@code setServletContext} (only applicable when running in a web application context) * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors * <li>InitializingBean's {@code afterPropertiesSet} * <li>a custom init-method definition * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors * </ol> * * <p>On shutdown of a bean factory, the following lifecycle methods apply: * 銷毀時: * <ol> * <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors * <li>DisposableBean's {@code destroy} * <li>a custom destroy-method definition * </ol> */ public interface BeanFactory { }