zoukankan      html  css  js  c++  java
  • 框架源码系列八:Spring源码学习之Spring核心工作原理(很重要)

    目录:
    一、搞清楚ApplicationContext实例化Bean的过程
    二、搞清楚这个过程中涉及的核心类
    三、搞清楚IOC容器提供的扩展点有哪些,学会扩展
    四、学会IOC容器这里使用的设计模式
    五、搞清楚不同创建方式的bean的创建过程

    一、ApplicationContext实例化bean的过程

    1. 找入口,扫描注册完beanDefinition后,要创建bean的实例,入口在哪里?

    AnnotationConfigApplicationContext context4 = new AnnotationConfigApplicationContext("com.study.leesmall.spring.service");
        /**
         * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
         * in the given packages and automatically refreshing the context.
         * @param basePackages the packages to check for annotated classes
         */
        public AnnotationConfigApplicationContext(String... basePackages) {
            this();
            scan(basePackages);
            refresh();
        }

    org.springframework.context.support.AbstractApplicationContext.refresh()方法就是入口了

        @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();
                }
            }
        }

    2.  读懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的处理流程

    1)准备context为了刷新

    // Prepare this context for refreshing.
                prepareRefresh();

    2)从子类获取BeanFactory实例

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

    3)准备BeanFactory为了使用context

                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    /**
         * Configure the factory's standard context characteristics,
         * such as the context's ClassLoader and post-processors.
         * @param beanFactory the BeanFactory to configure
         */
        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());
            }
        }

    重要1:

    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)) 这段代码很重要:

    如果你的bean实例里面需要ApplicationContext,你就需要实现ApplicationContextAwareProcessor这个接口,接口就会把ApplicationContext给到你的bean实例
    也可以通过autowired注解去获取,因为下面的这段代码:

    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    重要2:

    注解方式加载配置

    package com.study.leesmall.spring.ext;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    
    @Configuration
    @PropertySource("classpath:/application.properties")
    public class MyConfiguration {
    
        @Bean("messageSource")
        public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
            ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
            rms.setBasename("message");
            return rms;
        }
    }

    重要3:

    参数配置的优先级:命令参数 > 环境变量 > properties 文件

            // 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());
            }

    命令参数配置方式:进入要运行的类——run as——run configurations——弹出如下界面——选择——Arguments——添加参数

     环境变量参数配置方式:进入要运行的类——run as——run configurations——弹出如下界面——选择——Environment——添加参数

     

     properties 文件参数配置方式:直接在Resource目录下加入properties文件里面加入参数——在application.xml配置加载properties文件即可

    参数:

    # jdbc properties
    jdbc.driverClassName=xxxx
    jdbc.url=xxxx
    jdbc.username=xxxx
    jdbc.password=xxxx

     在application.xml配置加载properties文件

        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations" value="classpath:application.properties"/>
        </bean>

     4)对BeanFactory进行预处理

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

     说明:这里用了模板方法设计模式,需要子类去实现的

     5)调用执行BeanFactoryPostProcessor (这是一个很重要的扩展点,如果你想在Bean实例化前对BeanFactory进行处理的话,你就可以实现BeanFactoryPostProcessor接口及其子类如BeanDefinitionRegistryPostProcessor,示例如下面的排序优先级代码)

                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
        /**
         * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
         * respecting explicit order if given.
         * <p>Must be called before singleton instantiation.
         */
        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
            // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
            // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
            if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
        }

     委托给PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())执行

     这里要注意一下Spring里面有很多类似这样的委托处理

    代码详细解读:

     

    说明:

    BeanFactoryPostProcessor在实例化bean之前对BeanFactory进行处理的
    BeanPostProcessor在bean实例化后,对bean进行处理的
    这两个类用了观察者模式
    AbstractApplicationContextrefresh模板方法模式
    执行优先级:priorityOrded>orded

    执行顺序示例:

    优先排序的:

    package com.study.leesmall.spring.ext;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.core.PriorityOrdered;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanDefinitonRegistryPostProcessor3 implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被执行了。");
    
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被执行了。");
        }
    
        @Override
        public int getOrder() {
            return 1;
        }
    
    }

    普通排序的:

    package com.study.leesmall.spring.ext;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanDefinitonRegistryPostProcessor2 implements BeanDefinitionRegistryPostProcessor, Ordered {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被执行了。");
    
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被执行了。");
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    
    }

    没有排序的:

    package com.study.leesmall.spring.ext;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanDefinitonRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被执行了。");
    
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被执行了。");
        }
    
    }

    运行结果:

    --- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被执行了。
    --- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被执行了。
    --- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被执行了。
    --- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被执行了。
    --- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被执行了。
    --- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被执行了。

    6)向BeanFactory注册BeanPostProcessor(这是一个很重要的扩展点,如果你想在Bean实例化后对Bean进行处理的话)

    registerBeanPostProcessors(beanFactory)

    获得用户注册的BeanPostProcessor的bean定义,创建他们的实例,注册到BeanFactory,对bean实例化后进行处理

     7)initMessageSource();初始化国际化资源文件

    示例:

    package com.study.leesmall.spring.ext;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    
    //国际化 给入messageSource的bean实例到bean工厂
    @Configuration
    @PropertySource("classpath:/application.properties")
    public class MyConfiguration {
    
        @Bean("messageSource")
        public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
            ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
            rms.setBasename("message");
            return rms;
        }
    }

    8)initApplicationEventMulticaster 了解即可
    初始化Application Event广播器,把所有事件广播出去

    9)执行onRefresh(); 由子类来提供实现

    10)registerListeners() (这是一个很重要的扩展点,如果你想对容器工作过程中发生的节点事件进行一些处理,比如容器要刷新、容器要关闭了,那么你就可以实现ApplicationListener)
    注册ApplicationListener:获得用户注册的ApplicationListener的bean定义,创建他们的实例注册到第8步初始化的广播器上

    示例代码:

    package com.study.leesmall.spring.ext;
    
    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    
    //如果你想对容器工作过程中发生的节点事件进行一些处理,比如容器要刷新、容器要关闭了,那么你就可以实现ApplicationListener
    @Component
    public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            System.out.println("-----收到应用事件:" + event);
        }
    }

    11)finishBeanFactoryInitialization(beanFactory); 完成剩余的单例bean的实例化,为了提前实例化,后面不用getBean去创建实例

    a)什么时候实例化bean?
      单例bean可以在启动时实例化好,这样能提高使用时的效率
      原型bean在getBean(beanName)的时候实例化
    b)单例bean和原型bean实例化的过程有区别吗?
      没有区别的
    c)Spring中支持的bean实例创建的方式有几种?分别如何配置的,如何来获取Bean实例的?
      创建bean实例的方式:构造函数方式、工厂方式(静态工厂方式、非静态工厂方式)、实现FactoryBean的方式

    工厂方式创建bean实例示例代码:

    package com.study.leesmall.spring.sample.factory;
    
    import com.study.leesmall.spring.service.CombatService;
    import com.study.leesmall.spring.service.LoveService;
    import com.study.leesmall.spring.service.LoveServiceImpl;
    
    //工厂方式创建bean实例
    public class LoveServiceFactory {
    
        //静态工厂方式创建bean实例
        public static LoveService getLoveServiceFromStaticFactoryMethod() {
            return new LoveServiceImpl();
        }
    
        //非静态工厂方式创建bean实例
        public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
            return new CombatService(time);
        }
    }

    实现FactoryBean的方式创建bean实例示例代码:

    package com.study.leesmall.spring.sample.factory;
    
    import org.springframework.beans.factory.FactoryBean;
    
    import com.study.leesmall.spring.service.LoveService;
    import com.study.leesmall.spring.service.LoveServiceImpl;
    
    //实现FactoryBean的方式创建bean实例
    public class LoveServiceFactoryBean implements FactoryBean<LoveService> {
    
        @Override
        public LoveService getObject() throws Exception {
            return new LoveServiceImpl();
        }
    
        @Override
        public Class<?> getObjectType() {
            return LoveService.class;
        }
    
    }

    那么上面的创建bean实例的方式怎么在xm里面配置呢:

        <!--静态工厂方式的配置  -->
        <bean id="loveService" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory" 
            factory-method="getLoveServiceFromStaticFactoryMethod">
            <property name="combatService" ref="combatService"></property>
        </bean>
        <!--非静态工厂方式的配置  -->
        <bean id="loveServiceFactory" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory"> 
        </bean>
            <bean id="combatService" factory-bean="loveServiceFactory" factory-method="getCombatServiceFromMemberFactoryMethod">
            <constructor-arg type="int" value="60" />
        </bean>
        <!--实现FactoryBean的方式的配置  -->
        <bean name="loveService2" class="com.study.leesmall.spring.sample.factory.LoveServiceFactoryBean"></bean>

    那么注解方式又怎么配置呢:

    工厂方式创建bean实例注解配置:

    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    
    import com.study.leesmall.spring.service.CombatService;
    import com.study.leesmall.spring.service.LoveService;
    import com.study.leesmall.spring.service.LoveServiceImpl;
    
    //工厂方式创建bean实例
    @Component
    public class LoveServiceFactory {
    
        //静态工厂方式创建bean实例
        @Bean
        public static LoveService getLoveServiceFromStaticFactoryMethod() {
            return new LoveServiceImpl();
        }
    
        //非静态工厂方式创建bean实例
        @Bean
        public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
            return new CombatService(time);
        }
    }

    实现FactoryBean的方式创建bean实例注解配置:

    import org.springframework.beans.factory.FactoryBean;
    import org.springframework.stereotype.Component;
    
    import com.study.leesmall.spring.service.LoveService;
    import com.study.leesmall.spring.service.LoveServiceImpl;
    
    //实现FactoryBean的方式创建bean实例
    @Component
    public class LoveServiceFactoryBean implements FactoryBean<LoveService> {
    
        @Override
        public LoveService getObject() throws Exception {
            return new LoveServiceImpl();
        }
    
        @Override
        public Class<?> getObjectType() {
            return LoveService.class;
        }
    
    }

    代码跟踪:

    入口:org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

    数据类型的转换:

    // Initialize conversion service for this context.
            if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
                beanFactory.setConversionService(
                        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
            }

    数据类型的转换对应在xml配置里面的写法:

        <bean id="combatService" class="com.study.leesmall.spring.service.CombatService">
            <constructor-arg type="int" value="60" />
        </bean>

    初始化内嵌值的解析器,如properties文件里面配置的值就需要这种解析器:

        // Register a default embedded value resolver if no bean post-processor
            // (such as a PropertyPlaceholderConfigurer bean) registered any before:
            // at this point, primarily for resolution in annotation attribute values.
            if (!beanFactory.hasEmbeddedValueResolver()) {
                beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
            }

    AOP:bean实例初始化后,在进行代理增强,不创建原始bean实例,直接创建代理子类的实例

            // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
            String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
            for (String weaverAwareName : weaverAwareNames) {
                getBean(weaverAwareName);
            }

    提前实例化剩余的所有单例bean:

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

    说明:看子类的实现,过程是找到单例bean的名称,然后getBean(beanName)拿到单例bean的实例

    d)beanfactory中getBean()时的创建实例流程

    代码跟踪:

    入口:

    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

     

     

     

    下面来看一下真正创建bean实例的方法

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[]):

    看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])里面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String, RootBeanDefinition)

    方法:

     然后看一下上面调用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法:

     

    注意:

    这里又是一个扩展点, InstantiationAwareBeanPostProcessor 可以在 Bean 实例创建前、后进行增强处理

    如果你想在bean实例创建前后进行处理可以继承InstantiationAwareBeanPostProcessor的子类InstantiationAwareBeanPostProcessorAdaper,然后覆写里面你需要实现的方法,创建前处理就实现创建前处理的方法

    对比:
    BeanPostProcessor可以在bean实例初始化前和初始化后进行处理

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

    -> 

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])

     

    看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper)方法:

    继续看一下创建bean实例的代码块:

            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String, RootBeanDefinition, Object[])

     

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

    ->

    org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

     

    说明:

    explicitArgs:当你调用getBean的时候给定的造参数 spring在getbean的时候是可以自己传入构造参数的,可以不用bean定义里面指定或者xml里面配置的构造参数,示例如下:

    getbean(“loveService”, .....)

     

    拓展:

    工厂Bean和Bean工厂的区别:
    工厂Bean实现了FactoryBean接口的Bean
    Bean工厂BeanFactory IOC容器

    12)finishRefresh() 发布事件

    二、 搞清楚这个过程中涉及的核心类

    三、 搞清楚IOC容器提供的扩展点有哪些,学会扩展

    1. 扩展点:如第一个大标题

    一、ApplicationContext实例化bean的过程

    2.  读懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的处理流程

    的5)、6)、10)步均为扩展点

    5)调用执行BeanFactoryPostProcessor (这是一个很重要的扩展点,如果你想在Bean实例化前对BeanFactory进行处理的话,你就可以实现BeanFactoryPostProcessor接口及其子类如BeanDefinitionRegistryPostProcessor,示例如下面的排序优先级代码)

    6)向BeanFactory注册BeanPostProcessor(这是一个很重要的扩展点,如果你想在Bean实例化后对Bean进行处理的话)

    10)registerListeners() (这是一个很重要的扩展点,如果你想对容器工作过程中发生的节点事件进行一些处理,比如容器要刷新、容器要关闭了,那么你就可以实现ApplicationListener)
    注册ApplicationListener:获得用户注册的ApplicationListener的bean定义,创建他们的实例注册到第8步初始化的广播器上

    BeanDefinitionRegistryPostProcessor

    BeanFactoryPostProcessor

    BeanPostProcessorr

    ApplicationListener

    11)finishBeanFactoryInitialization(beanFactory); 完成剩余的单例bean的实例化,为了提前实例化,后面不用getBean去创建实例的

    然后看一下上面调用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法的讲解

    注意:

    这里又是一个扩展点, InstantiationAwareBeanPostProcessor 可以在 Bean 实例创建前、后进行增强处理

    如果你想在bean实例创建前后进行处理可以继承InstantiationAwareBeanPostProcessor的子类InstantiationAwareBeanPostProcessorAdaper,然后覆写里面你需要实现的方法,创建前处理就实现创建前处理的方法

    对比:
    BeanPostProcessor可以在bean实例初始化前和初始化后进行处理

    2. Spring容器启动时完成了哪几件核心事情:
    1)Bean定义的获得(解析xml或者扫描注解)
    2)环境的初始化 env
    3)BeanDefinitionRegistryPostProcessor的自动发现与执行
    4)BeanFactoryPostProcessor的自动发现与执行
    5)BeanPostProcessorr的自动发现与注册
    6)国际化资源初始化
    7)事件广播器的初始化
    8)ApplicationListener的自动发现与注册
    9)实例化单例bean

    四、 学会IOC容器这里使用的设计模式

    模板方法设计模式、观察者模式(主要是这两个)、策略模式、工厂模式

    搞清楚不同创建方式的bean的创建过程

     完整代码获取地址:https://github.com/leeSmall/FrameSourceCodeStudy/tree/master/spring-source-study

  • 相关阅读:
    Java 之 Maven 基础
    JavaScript 之 RegExp 对象
    Java 之 Jedis
    Java 之 Redis 基础
    Java 之 NOSQL
    JavaWeb 之 JSON
    JavaWeb 之 Ajax
    【LeetCode-数组】外观数列
    【LeetCode-树】从先序遍历还原二叉树
    【LeetCode-数组】搜索二维矩阵 II
  • 原文地址:https://www.cnblogs.com/leeSmall/p/10188408.html
Copyright © 2011-2022 走看看