Spring源碼分析-Bean的生命周期


先來一個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
  • 銷毀Bean:調用 destroy 方法的時候
我們先來通過源碼看一下Bean 創建的過程
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

 
1.實例化 bean
 
 
2.屬性注入
 
 
3.初始化 bean
 
接下來我們再看一下初始化 bean 有哪些操作?
AbstractAutowireCapableBeanFactory
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 的后初始化方法

 

 

3.1 調用實現XxxAware類的方法
 
下面這段代碼就是判斷是否實現了XxxAware 接口,並調用相應的setXxx 方法,調用 AbstractAutowireCapableBeanFactory 類中 invokeAwareMethods 方法
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 {
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM