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 为依赖注入值。

  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/10992272.html
Copyright © 2011-2022 走看看