【Spring源码分析】Bean的生命周期

参考:深究Spring中Bean的生命周期

1. 前言

  Spring两大核心技术IOC和AOP。而Bean的生命周期IOC技术中的一个重要内容,所以本篇文章想梳理下Spring中Bean的生命周期,加深对Bean生命周期的理解。

2. bean的扩展接口

  先来看个例子:

创建一个Book类,加上@Component标注这是一个Bean,

//Book.java

@Component
public class Book implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, BeanPostProcessor, InitializingBean,DisposableBean { public Book() { System.out.println("Book 正在调用Book()构造函数"); } @PostConstruct public void init() { System.out.println("Book 调用@PostConstruct注解的方法"); } @PreDestroy public void destrody() { System.out.println("Book 调用@PreDestroy注解的方法"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("Book 调用afterPropertiesSet()方法"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Book 调用setBeanFactory()方法"); } @Override public void setBeanName(String name) { System.out.println("Book 调用setBeanName()方法"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("Book 调用setBeanClassLoader()方法"); } @Override public void setEnvironment(Environment environment) { System.out.println("Book 调用setEnvironment()方法"); } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { System.out.println("Book 调用setEmbeddedValueResolver()方法"); } @Override public void destroy() throws Exception { System.out.println("Book 调用destroy()方法"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("Book 调用setApplicationContext()方法"); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("Book 调用setApplicationEventPublisher()方法"); } @Override public void setMessageSource(MessageSource messageSource) { System.out.println("Book 调用setMessageSource()方法"); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("Book 调用setResourceLoader()方法"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Book 调用postProcessBeforeInitialization()方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Book 调用postProcessAfterInitialization()方法"); return bean; } }

然后创建一个容器:

//main.java

public
class Main { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.scan("lu.ioc.lifecycle"); ac.refresh(); ac.close(); } }

运行程序,输出结果:

Book 正在调用Book()构造函数
Book 调用setBeanName()方法
Book 调用setBeanClassLoader()方法
Book 调用setBeanFactory()方法
Book 调用setEnvironment()方法
Book 调用setEmbeddedValueResolver()方法
Book 调用setResourceLoader()方法
Book 调用setApplicationEventPublisher()方法
Book 调用setMessageSource()方法
Book 调用setApplicationContext()方法
Book 调用@PostConstruct注解的方法
Book 调用afterPropertiesSet()方法
Book 调用@PreDestroy注解的方法
Book 调用destroy()方法

从以上的输出结果,可以看出Bean生命周期各接口的调用次序了。

图片来源:https://www.cnblogs.com/javazhiyin/p/10905294.html

 

上图的原图有个错误的地方,就是红框标注的地方,这里把错误给改正了。这里有点要说明的地方就是【调用自定义初始化方法】和【调用自定义销毁方法】,指的是Bean中被@PostConstruct和@PreDestroy修饰的方法。

细心的小伙伴可能已经发现了,为什么没有调用BeanPostProcessor接口的方法?

其实BeanPostProcessor叫后置处理器接口,是供其他Bean创建时调用的方法,比如有另外一个Bean:ShuXueBook,在该bean创建时,会调用Book的BeanPostProcessor接口实现方法。该接口的目的就是给用户修改创建Bean的扩展。

3.BeanFactory接口继承关系

上图中圆圈的代表接口,长方形代表类。

4、ApplicationContext接口继承关系

5. 源码分析

  对Spring的BeanFactoryApplicationContext接口有了初步的认识以后,下面开始源码分析。

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.scan("lu.ioc.lifecycle");
        ac.refresh();
        ac.close();
    }
}

//在
lu.ioc.lifecycle包下面有Main.javaconfig
//在lu.ioc.lifecycle.config包下面:
//Book.java
@Component
public class Book implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware,
ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, BeanPostProcessor,
InitializingBean,DisposableBean {
public Book() {
System.out.println("Book 正在调用Book()构造函数");
}

@PostConstruct
public void init() {
System.out.println("Book 调用@PostConstruct注解的方法");
}
@PreDestroy
public void destrody() {
System.out.println("Book 调用@PreDestroy注解的方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Book 调用afterPropertiesSet()方法");
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("Book 调用setBeanFactory()方法");
}

@Override
public void setBeanName(String name) {
System.out.println("Book 调用setBeanName()方法");
}

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Book 调用setBeanClassLoader()方法");
}

@Override
public void setEnvironment(Environment environment) {
System.out.println("Book 调用setEnvironment()方法");
}

@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("Book 调用setEmbeddedValueResolver()方法");
}

@Override
public void destroy() throws Exception {
System.out.println("Book 调用destroy()方法");
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("Book 调用setApplicationContext()方法");
}

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("Book 调用setApplicationEventPublisher()方法");
}

@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("Book 调用setMessageSource()方法");
}

@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("Book 调用setResourceLoader()方法");
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Book 调用postProcessBeforeInitialization()方法");
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Book 调用postProcessAfterInitialization()方法");
return bean;
}
}
//YuWenBook.java
@Component
public class YuWenBook implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware,
ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware,
InitializingBean,DisposableBean{
public YuWenBook() {
System.out.println("YuWenBook 正在调用Book()构造函数");
}

@PostConstruct
public void init() {
System.out.println("YuWenBook 调用@PostConstruct注解的方法");
}
@PreDestroy
public void destrody() {
System.out.println("YuWenBook 调用@PreDestroy注解的方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("YuWenBook 调用afterPropertiesSet()方法");
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("YuWenBook 调用setBeanFactory()方法");
}

@Override
public void setBeanName(String name) {
System.out.println("YuWenBook 调用setBeanName()方法");
}

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("YuWenBook 调用setBeanClassLoader()方法");
}

@Override
public void setEnvironment(Environment environment) {
System.out.println("YuWenBook 调用setEnvironment()方法");
}

@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("YuWenBook 调用setEmbeddedValueResolver()方法");
}

@Override
public void destroy() throws Exception {
System.out.println("YuWenBook 调用destroy()方法");
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("YuWenBook 调用setApplicationContext()方法");
}

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("YuWenBook 调用setApplicationEventPublisher()方法");
}

@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("YuWenBook 调用setMessageSource()方法");
}

@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("YuWenBook 调用setResourceLoader()方法");
}
}
public class Main {
    public static void main(String[] args) {
     //创建一个Spring容器上下文对象 AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(); //扫描 lu.ioc.lifecycle包下面的class文件,识别出spring要管理的Bean,然后定义成BeanDefinition。
  ac.scan(
"lu.ioc.lifecycle");
     //这里是重点 ac.refresh(); ac.close(); } }

//ac.refresh()进入的代码如下:AbstractApplicationContext.java 




@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
 

其实生命周期方法是在 prepareBeanFactory(beanFactory) 函数中添加的,进入:

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Register early post-processor for detecting inner beans as ApplicationListeners.
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

我们来看下红色部分的代码 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

 这里着重看下ApplicationContextAwareProcessor.java 这个类

class ApplicationContextAwareProcessor implements BeanPostProcessor {

    private final ConfigurableApplicationContext applicationContext;

    private final StringValueResolver embeddedValueResolver;


    /**
     * Create a new ApplicationContextAwareProcessor for the given context.
     */
    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }


    @Override
    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
            return bean;
        }

        AccessControlContext acc = null;

        if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }

看到这里大家应该知道Spring是如何提供可扩展的Aware接口了吧。

 

posted @ 2020-02-13 21:15  lqwh  阅读(321)  评论(0编辑  收藏  举报