zoukankan      html  css  js  c++  java
  • 回炉Spring--事务及Spring源码

    声明式事务

    配置文件信息:

    /**
     * @EnableTransactionManagement 开启基于注解的事务管理功能
     * 1、配置数据源
     * 2、配置事务管理器来管理事务
     * 3、给方法上标注 @Transactional 表示当前方法是一个事务方法,@Transaction默认回滚Error和RuntimeException,但是不包括和RuntimeException
    * 一样同属于Exception子类的如IOException、SQLException和自定义异常等,对于这些异常如果也要回滚要在rollbackFor中指定
    */ @EnableTransactionManagement @Configuration public class TxConfig { @Bean public DataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser("yang"); dataSource.setPassword("yang"); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); return dataSource; } /** * 如果bean之间有依赖,直接放进参数中即可,参数值会从Spring容器中取,然后赋值 * 参数从Spring容器中取 * * @param dataSource * @return */ @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // 也可以直接调用,Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件 // JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } /** * 注册事务管理器在容器中 * * @return * @throws Exception */ @Bean public PlatformTransactionManager transactionManager() throws Exception { return new DataSourceTransactionManager(dataSource()); } }

    @EnableTransactionManagement 做了什么?

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(TransactionManagementConfigurationSelector.class)
    public @interface EnableTransactionManagement {
    
        boolean proxyTargetClass() default false;
    
        AdviceMode mode() default AdviceMode.PROXY;
    
        int order() default Ordered.LOWEST_PRECEDENCE;
    }

    1、导入了TransactionManagementConfigurationSelector,TransactionManagementConfigurationSelector往容器中导入了两个组件

      AutoProxyRegistrar 、ProxyTransactionManagementConfiguration

    /**
         * Returns {@link ProxyTransactionManagementConfiguration} or
         * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
         * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
         * respectively.
         */
        @Override
        protected String[] selectImports(AdviceMode adviceMode) {
            switch (adviceMode) {
                case PROXY:
                    return new String[] {AutoProxyRegistrar.class.getName(),
                            ProxyTransactionManagementConfiguration.class.getName()};
                case ASPECTJ:
                    return new String[] {determineTransactionAspectClass()};
                default:
                    return null;
            }
        }
    
        private String determineTransactionAspectClass() {
            return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
                    TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
                    TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
        }
    
    //     public static final String JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
                "org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration";
    
    //     public static final String TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
                "org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";

    (1)、AutoProxyRegistrar

      给容器中注册了一个beanNameorg.springframework.aop.config.internalAutoProxyCreator,类型为InfrastructureAdvisorAutoProxyCreator

    的组件(bean),其是一个后置处理器,和AOP中的AnnotationAwareAspectJAutoProxyCreator类似,它们beanName相同。

    都是在对象创建完成之后利用后置处理器的初始化后置方法,包装对象,然后返回一个包含增强器的代理对象,代理对象执行方法利用拦截器链进行调用。

     (2)、ProxyTransactionManagementConfiguration是一个配置文件类

    /**
     * {@code @Configuration} class that registers the Spring infrastructure beans
     * necessary to enable proxy-based annotation-driven transaction management.
     *
     * @author Chris Beams
     * @since 3.1
     * @see EnableTransactionManagement
     * @see TransactionManagementConfigurationSelector
     */
    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
        @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { // 事务增强器
            BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor());
            if (this.enableTx != null) {
                advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            }
            return advisor;
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionInterceptor transactionInterceptor() { // 事务拦截器
            TransactionInterceptor interceptor = new TransactionInterceptor();
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            if (this.txManager != null) {
                interceptor.setTransactionManager(this.txManager);
            }
            return interceptor;
        }
    
    }

      1、往容器中注册事务增强器transactionAdvisor,其中事务增强器中又依赖了:

        1):事务增强器要用事务注解的参数信息,TransactionAttributeSource,AnnotationTransactionAttributeSource来解析事务注解

        2):事务拦截器:TransactionInterceptor,保存了事务属性信息,事务管理器。其实现了MethodInterceptor接口。在目标方法执行

        的时候:执行拦截器链,然后执行事务拦截器:

          (1):先获取事务相关的属性

          (2):再获取PlatformTransactionManager事务管理器,如果在@Transactional注解中没有指定transactionManager,则最终会

          从容器中按照类型获取一个PlatformTransactionManager

          (3):执行目标方法

          如果异常,获取到事务管理器,利用事务管理回滚操作

          【transactionInfo.getTransactionManager().rollback(txInfo.getTransactionStatus())】

          如果正常,利用事务管理器,提交事务【transactionInfo.getTransactionManager().commit(txInfo.getTransactionStatus());】

        TransactionInterceptor#invoke

        @Override
        @Nullable
        public Object invoke(MethodInvocation invocation) throws Throwable {
            // Work out the target class: may be {@code null}.
            // The TransactionAttributeSource should be passed the target class
            // as well as the method, which may be from an interface.
            Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    
            // Adapt to TransactionAspectSupport's invokeWithinTransaction...
            return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
        }

        @Transactional注解处理器的核心代码,TransactionAspectSupport#invokeWithinTransaction:278,从TransactionInterceptor#invoke进入

      /**
         * General delegate for around-advice-based subclasses, delegating to several other template
         * methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
         * as well as regular {@link PlatformTransactionManager} implementations.
         * @param method the Method being invoked
         * @param targetClass the target class that we're invoking the method on
         * @param invocation the callback to use for proceeding with the target invocation
         * @return the return value of the method, if any
         * @throws Throwable propagated from the target invocation
         */
        @Nullable
        protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
                final InvocationCallback invocation) throws Throwable {
    
            // If the transaction attribute is null, the method is non-transactional.
            TransactionAttributeSource tas = getTransactionAttributeSource();
            final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
            final PlatformTransactionManager tm = determineTransactionManager(txAttr); // 确定要用于给定交易的特定交易管理器
            final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    
            if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
                // Standard transaction demarcation with getTransaction and commit/rollback calls.
                TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); // 开启事务
                Object retVal = null;
                try {
                    // This is an around advice: Invoke the next interceptor in the chain.
                    // This will normally result in a target object being invoked.
                    retVal = invocation.proceedWithInvocation(); // 执行业务方法
                }
                catch (Throwable ex) {
                    // target invocation exception
                    completeTransactionAfterThrowing(txInfo, ex); // 回滚事务
                    throw ex; // 仍往上抛出异常,供上层捕获
                }
                finally {
                    cleanupTransactionInfo(txInfo); // Reset the TransactionInfo ThreadLocal.
                }
                commitTransactionAfterReturning(txInfo); // 提交事务
                return retVal;
            }
    
            else {
                ...
            }
        }

      回滚事务:

      /**
         * Handle a throwable, completing the transaction.
         * We may commit or roll back, depending on the configuration.
         * @param txInfo information about the current transaction
         * @param ex throwable encountered
         */
        protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
            if (txInfo != null && txInfo.getTransactionStatus() != null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                            "] after exception: " + ex);
                }
                if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
                    try {
                        txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
                    }
                    catch (TransactionSystemException ex2) {
                        logger.error("Application exception overridden by rollback exception", ex);
                        ex2.initApplicationException(ex);
                        throw ex2;
                    }
                    catch (RuntimeException | Error ex2) {
                        logger.error("Application exception overridden by rollback exception", ex);
                        throw ex2;
                    }
                }
                else {
                    // We don't roll back on this exception.
                    // Will still roll back if TransactionStatus.isRollbackOnly() is true.
                    // 默认回滚(ex instanceof RuntimeException || ex instanceof Error) 异常,其他异常不会回滚,仍提交事务
                    try {
                        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
                    }
                    catch (TransactionSystemException ex2) {
                        logger.error("Application exception overridden by commit exception", ex);
                        ex2.initApplicationException(ex);
                        throw ex2;
                    }
                    catch (RuntimeException | Error ex2) {
                        logger.error("Application exception overridden by commit exception", ex);
                        throw ex2;
                    }
                }
            }
        }

       最终回滚代码为:DataSourceTransactionManager#doRollback

    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    con.rollback();

      提交事务:

        /**
         * Execute after successful completion of call, but not after an exception was handled.
         * Do nothing if we didn't create a transaction.
         * @param txInfo information about the current transaction
         */
        protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
            if (txInfo != null && txInfo.getTransactionStatus() != null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
                }
                txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); // 提交事务
            }
        }

       最终提交代码为:

    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    con.commit();

      

     拓展原理

      BeanPostProcessor:bean的后置处理器,在bean创建对象之后的初始化前后做一些拦截工作

    一、BeanFactoryPostProcessor:beanFactory的后置处理器,在BeanFactory初始化之后调用【postProcessBeanFactory()】,来定制和修改BeanFactory的内容,这时候所有的bean定义都已经保存到了beanFactory中,但是bean的实例还未创建

    BeanFactoryPostProcessor执行时机和原理:

        1、创建Spring容器

        2、refresh()-->invokeBeanFactoryPostProcessors(beanFactory);

          1):直接在BeanFactory中找到所有类型是BeanFactoryProcessor的组件,并执行它们的方法

          2):在初始化创建其他组件前面执行

    二、BeanDefinitionRegistryPostProcessor【BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor】

      postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);在所有的bean定义信息将要被加载,bean实例还未创建。

      因此在BeanFactoryPostProcessor的postProcessBeanFactory()之前执行,可以利用其往容器中再额外添加一些组件,如:

      RootBeanDefinition beanDefinition = new RootBeanDefinition(Computer.class);

      registry.registerBeanDefinition("computer", beanDefinition);

     BeanDefinitionRegistryPostProcessor执行时机和原理:

        1、创建Spring容器

        2、refresh()-->invokeBeanFactoryPostProcessors(beanFactory);

        3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件

          1):依次触发所有的postProcessBeanDefinitionRegistry()方法

          2):再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;

        4、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法

    三、ApplicationListener

      监听容器中发布的事件。事件驱动模型开发。监听ApplicationEvent及其子类事件

    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
        /**
         * Handle an application event.
         * @param event the event to respond to
         */
        void onApplicationEvent(E event);
    
    }

    监听事件步骤:

      1、自定义监听器实现ApplicationListener来监听某个事件(ApplicationEvent及其子类)

      2、把监听器注册到Spring容器中@Component

      3、只要容器中有相关事件的发布,我们就能监听到这个事件

        ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件

        ContextClosedEvent:关闭容器会发布这个事件

      4、如何发布一个事件: applicationContext.publishEvent(); 如:【applicationContext.publishEvent(new ContextStartedEvent(applicationContext));】

    监听原理:

      以ContextRefreshedEvent事件为例:

      1、创建Spring容器

      2、refresh()-->finishRefresh();  refresh的最后一步完成容器刷新进行事件发布

      3、publishEvent(new ContextRefreshedEvent(this));

        事件发布流程:

          1):获取事件的多播器(派发器)

          2):multicastEvent 派发事件

          【getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);】

          3):获取到所有的上下文监听器的集合 getApplicationListeners(event, type),然后遍历

            (1)、如果线程池Executor不为null,则使用Executor进行异步派发

            (2)、否则,以同步的方式直接执行listener方法:【invokeListener(listener, event);】,拿到listener然后调用其的

            【listener.onApplicationEvent(event); 】

       

    那流程中的事件多播器如何获取呢?

      1、创建Spring容器

      2、refresh()-->initApplicationEventMulticaster(); 在registerBeanPostProcessors(beanFactory);之后为容器初始化事件多播器

        1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
        2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;

    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
                beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

    容器中有哪些监听器呢?

      1、创建Spring容器

      2、refresh()-->registerListeners();  从容器中检查到所有的监听器bean并将它们注册到applicationEventMulticaster中

    for (ApplicationListener<?> listener : getApplicationListeners()) {
                getApplicationEventMulticaster().addApplicationListener(listener);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let post-processors apply to them!
            String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
            for (String listenerBeanName : listenerBeanNames) {
                getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
            }

    监听事件除了自定义监听器实现ApplicationListener,也可以使用@EventListener标注在方法上指定监听的事件,当事件发生时就会触发方法执行

        @EventListener(classes = ApplicationEvent.class)
        public void listen(ApplicationEvent event) {
            // doSomeThing
        }

      @EventListener的原理是通过EventListenerMethodProcessor 处理器解析方法上的@EventListener注解来实现的。

      【public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware】

      SmartInitializingSingleton:

    public interface SmartInitializingSingleton {
    
        /**
         * Invoked right at the end of the singleton pre-instantiation phase,
         * with a guarantee that all regular singleton beans have been created
         * already. {@link ListableBeanFactory#getBeansOfType} calls within
         * this method won't trigger accidental side effects during bootstrap.
         * <p><b>NOTE:</b> This callback won't be triggered for singleton beans
         * lazily initialized on demand after {@link BeanFactory} bootstrap,
         * and not for any other bean scope either. Carefully use it for beans
         * with the intended bootstrap semantics only.
         */
        void afterSingletonsInstantiated();
    
    }

     SmartInitializingSingleton原理:

      再次说【finishBeanFactoryInitialization(beanFactory);】,完成BeanFactory初始化工作,创建剩下的除了BeanPostProcessor之外的单实例bean;

      refresh()--> finishBeanFactoryInitialization(beanFactory);--> beanFactory.preInstantiateSingletons();--> smartSingleton.afterSingletonsInstantiated();

    DefaultListableBeanFactory:
    @Override
        public void preInstantiateSingletons() throws BeansException {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Pre-instantiating singletons in " + this);
            }
    
            // Iterate over a copy to allow for init methods which in turn register new bean definitions.
            // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
            List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    
            // Trigger initialization of all non-lazy singleton beans...创建所有的单实例bean
            for (String beanName : beanNames) {
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    if (isFactoryBean(beanName)) {
                        final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                                @Override
                                public Boolean run() {
                                    return ((SmartFactoryBean<?>) factory).isEagerInit();
                                }
                            }, getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                    else {
                        getBean(beanName);
                    }
                }
            }
    
            // Trigger post-initialization callback for all applicable beans...创建完之后,判断其是否是SmartInitializingSingleton类型,是的话,调用afterSingletonsInstantiated();
            for (String beanName : beanNames) {
                Object singletonInstance = getSingleton(beanName);
                if (singletonInstance instanceof SmartInitializingSingleton) {
                    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
                            @Override
                            public Object run() {
                                smartSingleton.afterSingletonsInstantiated();
                                return null;
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        smartSingleton.afterSingletonsInstantiated();
                    }
                }
            }
        }

      1)、先创建所有的单实例bean;getBean();

      2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();

      3)、EventListenerMethodProcessor 在重写SmartInitializingSingleton接口的afterSingletonsInstantiated()方法上对bean方法上的@EventListener注解进行处理,实现其监听功能

    protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
            if (!this.nonAnnotatedClasses.contains(targetType)) {
                Map<Method, EventListener> annotatedMethods = null;
                try {
                    annotatedMethods = MethodIntrospector.selectMethods(targetType,
                            new MethodIntrospector.MetadataLookup<EventListener>() {
                                @Override
                                public EventListener inspect(Method method) {
                                    return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
                                }
                            });
                }
                catch (Throwable ex) {
                    // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
                    if (logger.isDebugEnabled()) {
                        logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
                    }
                }
                if (CollectionUtils.isEmpty(annotatedMethods)) {
                    this.nonAnnotatedClasses.add(targetType);
                    if (logger.isTraceEnabled()) {
                        logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
                    }
                }
                else {
                    // Non-empty set of methods
                    for (Method method : annotatedMethods.keySet()) {
                        for (EventListenerFactory factory : factories) {
                            if (factory.supportsMethod(method)) {
                                Method methodToUse = AopUtils.selectInvocableMethod(
                                        method, this.applicationContext.getType(beanName));
                                ApplicationListener<?> applicationListener =
                                        factory.createApplicationListener(beanName, targetType, methodToUse);
                                if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                                    ((ApplicationListenerMethodAdapter) applicationListener)
                                            .init(this.applicationContext, this.evaluator);
                                }
                                this.applicationContext.addApplicationListener(applicationListener);
                                break;
                            }
                        }
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
                                beanName + "': " + annotatedMethods);
                    }
                }
            }
        }

    梳理Spring容器创建及初始化过程

    AbstractApplicationContext:

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

    1、prepareRefresh()  刷新前的预处理

      1)-->initPropertySources();  初始化一些属性配置资源文件到容器中的environment对象中,子类需自定义属性初始化方法

      2)-->getEnvironment().validateRequiredProperties();  获取属性内容并校验合法性等

      3)-->this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();  初始化用来保存容器中的一些早期事件

    2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  获取beanFactory

      1):refreshBeanFactory();  刷新【创建】BeanFactory;创建了一个this.beanFactory = new DefaultListableBeanFactory();设置并设置serializationId;

      2):ConfigurableListableBeanFactory beanFactory = getBeanFactory();  返回上一步创建的beanFactory

      3):默认的beanFactory是DefaultListableBeanFactory

    3、prepareBeanFactory(beanFactory);  beanFactory的预准备工作,对其属性赋值

      1):设置beanFactory的类加载器,支持表达式解析器等

      2):添加部分后置处理器,如【beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));】ApplicationListenerDetector等

      3):设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware等;

      4):注册可以解析的依赖;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext

      5):添加编译时的AspectJ支持

      6):给BeanFactory中注册一些能用的组件;

          environment【ConfigurableEnvironment】、
          systemProperties【Map<String, Object>】、
          systemEnvironment【Map<String, Object>】

    4、postProcessBeanFactory(beanFactory);  BeanFactory准备工作完成后进行的后置处理工作,此时bean的定义信息还未加载

      此方法默认没有方法体,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

    以上是beanFactory的创建及预准备工作。

    5、invokeBeanFactoryPostProcessors(beanFactory);  实例化并调用所有注册的BeanFactoryPostProcessor执行其方法,

      beanFactory的后置处理器,其postProcessBeanFactory()方法在beanFactory标准初始化之后执行的,这时候所有bean定义都将被加载,但是还没有bean被实例化,这时允许重写或者添加bean的属性。

      不过BeanFactoryPostProcessor有个子接口BeanDefinitionRegistryPostProcessor,其方法postProcessBeanDefinitionRegistry在所有常规bean定义都将被加载,但是还没有bean被实例化,这时允许在下一个后处理阶段开始之前添加bean的定义信息

      1)、先执行BeanDefinitionRegistryPostProcessor
        (1)、从beanFactory中获取所有的BeanDefinitionRegistryPostProcessor;
        (2)、先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor【postProcessor.postProcessBeanDefinitionRegistry(registry)】
        (3)、再次执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor【postProcessor.postProcessBeanDefinitionRegistry(registry)】
        (4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors【postProcessor.postProcessBeanDefinitionRegistry(registry)】
            
      2)、再执行BeanFactoryPostProcessor的方法
        (1)、从beanFactory中获取所有的BeanFactoryPostProcessor
        (2)、先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
        (3)、再执行实现了Ordered顺序接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
        (4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
          

    6、registerBeanPostProcessors(beanFactory);  注册并实例化所有的BeanPostProcessor,bean的后置处理器,用来拦截bean的创建过程

      不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
      BeanPostProcessor、
      DestructionAwareBeanPostProcessor、
      InstantiationAwareBeanPostProcessor、
      SmartInstantiationAwareBeanPostProcessor、
      MergedBeanDefinitionPostProcessor:

        if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
        }

      1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
      2)、先注册实现了PriorityOrdered优先级接口的BeanPostProcessor;把每一个BeanPostProcessor;添加到BeanFactory中【beanFactory.addBeanPostProcessor(postProcessor);】
      3)、再注册实现了Ordered接口的
      4)、最后注册没有实现任何优先级接口的
      5)、最终注册MergedBeanDefinitionPostProcessor;
      6)、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是applicationContext.addApplicationListener((ApplicationListener<?>) bean);

    7、initMessageSource();  初始化MessageSource组件(做国际化功能;消息绑定,消息解析);

      1):获取BeanFactory

      2):看容器中是否有id为messageSource的,类型是MessageSource的组件,如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;

        MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;

      3):把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;

        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);

    8、initApplicationEventMulticaster();  初始化事件派发器 

      1)、获取BeanFactory
      2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
      3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
      4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入

    9、onRefresh();  留给子容器(子类)

      子类重写这个方法,在容器刷新的时候可以自定义逻辑;

    10、registerListeners();  给容器中将项目里面所有的ApplicationListener注册进来

      1)、从容器中拿到所有的ApplicationListener

      2)、将每个监听器添加到事件派发器中;【getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);】

      3)、派发之前步骤产生的事件;

    11、finishBeanFactoryInitialization(beanFactory);  初始化所有剩下的单实例bean,因为BeanPostFactory类型的bean已经已经创建完成了

      beanFactory.preInstantiateSingletons();

      1):获取容器中所有的beanNames(ArrayList<String>),遍历并依次进行初始化和创建对象

      2):根据beanName从【ConcurrentHashMap<String, RootBeanDefinition>】获取每一个bean的定义信息RootBeanDefinition

      3):判断如果当前bean不是抽象的,是单例的和是懒加载的则:

        (1):判断bean是否实现了FactoryBean接口,如果是则用工厂方法创建对象

        (2):如果不是,getBean(beanName);  来创建对象,和【applicationContext.getBean("beanName");】执行代码相同

          1、doGetBean(name, null, null, false)

          2、getSingleton(String beanName)  获取到了直接返回bean实例

            1):先从缓存【private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);】中获取保存的单实例

               Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来);

            2):如果singletonObjects 中没有,再从当前创建bean池中去获取

              【private final Set<String> singletonsCurrentlyInCreation=Collections.newSetFromMap(newConcurrentHashMap<String, Boolean>(16));】

            3):如果beanName在当前创建bean池中,则尝试从earlySingletonObjects缓存中获取

              【private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);】

            4):如果earlySingletonObjects中也没有,则再次尝试从singletonFactories中获取提前曝光的ObjectFactory,如果根据beanName找到了ObjectFactory,

                 则从ObjectFactory中获取bean实例,然后将其放在earlySingletonObjects 缓存中,再将其ObjectFactory从singletonFactories中移除

            因为在创建单实例bean的时候会存在依赖注入的情况,为了避免循环依赖,Spring在创建bean的过程中,若发现有依赖bean,则尝试去创建依赖的bean,因

            此Spring将每一个正在创建的bean的beanName放在一个“当前创建bean池”中,bean在创建过程中,BeanName将一直存在这个池中。另外,为了避免循环依

            赖,在Spring中创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则

            直接使用ObjectFactory去获取依赖bean的实例。

          3、如果获取不到,开始创建流程,先标记bean已经创建,避免多线程创建多个bean【markBeanAsCreated(beanName);】

          4、获取当前bean的定义信息,并校验合法性【

            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);】

          5、获取当前bean的所有依赖bean【String[] dependsOn = mbd.getDependsOn();】如果不为空,则依此创建其依赖bean【getBean(depBeanName);】回到步骤(2)

          6、启动单实例bean的创建流程,使用用ObjectFactory

            sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                catch (BeansException ex) {
                                    // Explicitly remove instance from singleton cache: It might have been put there
                                    // eagerly by the creation process, to allow for circular reference resolution.
                                    // Also remove any beans that received a temporary reference to the bean.
                                    destroySingleton(beanName);
                                    throw ex;
                                }
                            }
                        });

            1):createBean(beanName, mbd, args);

            2):Object bean = resolveBeforeInstantiation(beanName, mbdToUse);  尝试让InstantiationAwareBeanPostProcessor先拦截返回代理对象

              拿到所有的BeanPostProcessor【getBeanPostProcessors()】并遍历,如果有InstantiationAwareBeanPostProcessor类型的BeanPostProcessor,则让

              InstantiationAwareBeanPostProcessor的后置处理器提前执行,先触发其【postProcessBeforeInstantiation(beanClass, beanName);】如果其返回的对象不为

              空,则执行所有BeanPostProcessor的postProcessAfterInitialization返回其代理对象,然后结束bean对象的创建。如果返回的对象为空,继续步骤3)

              (亲测,即使切面的目标类在此时返回的也是空,会继续后面的doCreateBean),因此切面的代理类是在bean实例化之后的InstantiationAwareBeanPostProcessor的

              postProcessAfterInitialization方法中创建代理对象的。

            3):Object beanInstance = doCreateBean(beanName, mbdToUse, args);

              (1):BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);  利用工厂方法或者对象的构造器创建出Bean实例

              (2):applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  执行MergedBeanDefinitionPostProcessor后置处理器的

                   postProcessMergedBeanDefinition(mbd, beanType, beanName)方法

              (3):populateBean(beanName, mbd, instanceWrapper);  给bean的属性赋值

                赋值之前有1、2、3三步:

                1、遍历所有的后置处理器,只执行InstantiationAwareBeanPostProcessor类型的后置处理器的postProcessAfterInstantiation方法,如果其返回false,则停止

                  赋值操作return;

                2、依此byName和byType自动装配为bean的依赖注入值

                3、遍历所有的后置处理器,只执行InstantiationAwareBeanPostProcessor类型的后置处理器的postProcessPropertyValues,如果返回pvs==null,则停止下

                  面的赋值操作并return;

                3、applyPropertyValues(beanName, mbd, bw, pvs);  应用Bean属性的值;为属性利用setter方法等进行赋值;

              (4):initializeBean(beanName, exposedObject, mbd);  Bean初始化

                1、invokeAwareMethods(beanName, bean);  如果bean实现了xxxAware接口,则调用其的setXxx方法为bean的xxx属性赋值

                2、wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);执行所有的BeanPostProcessor后置处理器的

                  postProcessBeforeInitialization方法

                3、invokeInitMethods(beanName, wrappedBean, mbd);  执行初始化方法

                  1):如果bean实现了InitializingBean接口,则执行其afterPropertiesSet()方法

                  2):String initMethodName = mbd.getInitMethodName();获取自定义初始化方法,如果有自定义初始化方法,则执行其自定义初始化方法

                      invokeCustomInitMethod(beanName, bean, mbd);

                4、wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);执行所有的BeanPostProcessor后置处理器的

                  postProcessAfterInitialization方法(创建bean的代理在此执行的)

              (5):registerDisposableBeanIfNecessary(beanName, bean, mbd);  注册bean的销毁方法

              (6):返回bean实例

            4)、afterSingletonCreation(String beanName)  将beanName从singletonsCurrentlyInCreation移除

            5)、addSingleton(beanName, singletonObject);  

                this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
                this.singletonFactories.remove(beanName);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);

            所以Spring容器就是这些各种Map,保存了单实例bean,环境信息等。

      4):遍历beanNames,根据beanName拿到每一个bean实例,判断其是否实现了SmartInitializingSingleton接口,如果实现了则调用其afterSingletonsInstantiated()方法

      完成BeanFactory的初始化创建工作;IOC容器就创建完成;

    12、finishRefresh();

      1)、initLifecycleProcessor();  初始化和生命周期有关的后置处理器:LifecycleProcessor
        默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();加入到容器;

        如果我们写一个LifecycleProcessor的实现类,那么下面的方法在BeanFactory进行到相应的生命周期处就会进行调用
          void onRefresh();
          void onClose();

      2)、getLifecycleProcessor().onRefresh();  拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();

      3)、publishEvent(new ContextRefreshedEvent(this));  发布容器刷新完成事件;

      4)、LiveBeansView.registerApplicationContext(this);  

    总结:

    1、Spring容器启动的时候,先会保存所有注册进来的Bean的定义信息

      1):xml注册bean:<bean>

      2):注解注册Bean;@Service、@Component、@Bean、xxx

    2、Spring容器会合适的时机创建这些Bean

      1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
      2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();

    3、非常重要的BeanPostProcessor,后置处理器

      1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;

        AutowiredAnnotationBeanPostProcessor:处理自动注入
        AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;

        AsyncAnnotationBeanPostProcessor:异步相关

        ScheduledAnnotationBeanPostProcessor:调度相关

        等等

    4、事件驱动模型;

      ApplicationListener;事件监听
      ApplicationEventMulticaster;事件派发

    问题汇总:

    Spring如何实现DI及时机?

      AutowiredAnnotationBeanPostProcessor:处理自动注入

    public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
            implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware ;
        public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor;
            public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor;

      1、在doGetBean中执行createBean之前,先获取当前bean的所有依赖bean【String[] dependsOn = mbd.getDependsOn();】如果不为空,则依此创建其依赖

    bean【getBean(depBeanName);】

      2、在populateBean(beanName, mbd, instanceWrapper);  给bean的属性赋值,这一步中,先执行InstantiationAwareBeanPostProcessor的后置处理器,

      即用AutowiredAnnotationBeanPostProcessor 为依赖注入值。

  • 相关阅读:
    类型转换
    with语句用法
    微软工具下载网址
    第2章信息系统服务管理
    声明变量
    管理机中录入485总表的操作方法
    任务 uitableview uiscrollview uiresponder
    如何去掉UITableViewController中的分隔线setSeparatorStyle
    NSRunLoop 概述和原理
    使用 Notifications
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/10992272.html
Copyright © 2011-2022 走看看