• 【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接口了吧。

  • 相关阅读:
    数据安全:1.98亿购车者的购车记录公之于众
    【作者面对面问答】包邮送《Redis 5设计与源码分析》5本
    关于区块链学习资料
    《机器学习》周志华西瓜书学习笔记(九):聚类
    Bulletproof零知识证明
    数据接收合并
    数据接收合并
    数据接收合并
    数据接收合并
    Tomcat 8 Host-Manager配置访问的方法,全网唯一正确配置
  • 原文地址:https://www.cnblogs.com/lqwh/p/12304876.html
Copyright © 2020-2023  润新知