• 【Spring源码分析】非懒加载的单例Bean初始化前后的一些操作


    前言

    之前两篇文章【Spring源码分析】非懒加载的单例Bean初始化过程(上篇)【Spring源码分析】非懒加载的单例Bean初始化过程(下篇)比较详细地分析了非懒加载的单例Bean的初始化过程,整个流程始于AbstractApplicationContext的refresh()方法:

    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) {
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
        }
    }

    之前重点分析的是finishBeanFactoryInitialization方法,这个方法完成了所有非懒加载的单例Bean的初始化。今天我回头重看了一下refresh()方法,发现前面有一些方法还是忽略了没有去特别在意,其实他们都是Spring整个启动流程中的重要组成部分,下面就来分析一下finishBeanFactoryInitialization方法前面的一些方法。

    obtainFreshBeanFactory方法之前已经详细分析过了,就从prepareBeanFactory方法开始。

    PrepareBeanFactory方法

    看一下PrepareBeanFactory方法的实现:

     1 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
     2     // Tell the internal bean factory to use the context's class loader etc.
     3     beanFactory.setBeanClassLoader(getClassLoader());
     4     beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
     5     beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
     6 
     7     // Configure the bean factory with context callbacks.
     8     beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
     9     beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    10     beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    11     beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    12     beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    13 
    14     // BeanFactory interface not registered as resolvable type in a plain factory.
    15     // MessageSource registered (and found for autowiring) as a bean.
    16     beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    17     beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    18     beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    19     beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    20 
    21     // Detect a LoadTimeWeaver and prepare for weaving, if found.
    22     if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    23         beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    24         // Set a temporary ClassLoader for type matching.
    25         beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    26     }
    27 
    28     // Register default environment beans.
    29     if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    30         Map systemProperties;
    31         try {
    32             systemProperties = System.getProperties();
    33         }
    34         catch (AccessControlException ex) {
    35             systemProperties = new ReadOnlySystemAttributesMap() {
    36                 @Override
    37                 protected String getSystemAttribute(String propertyName) {
    38                     try {
    39                         return System.getProperty(propertyName);
    40                     }
    41                     catch (AccessControlException ex) {
    42                         if (logger.isInfoEnabled()) {
    43                             logger.info("Not allowed to obtain system property [" + propertyName + "]: " +
    44                                     ex.getMessage());
    45                         }
    46                         return null;
    47                     }
    48                 }
    49             };
    50         }
    51         beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
    52     }
    53 
    54     if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    55         Map<String,String> systemEnvironment;
    56         try {
    57             systemEnvironment = System.getenv();
    58         }
    59         catch (AccessControlException ex) {
    60             systemEnvironment = new ReadOnlySystemAttributesMap() {
    61                 @Override
    62                 protected String getSystemAttribute(String variableName) {
    63                     try {
    64                         return System.getenv(variableName);
    65                     }
    66                     catch (AccessControlException ex) {
    67                         if (logger.isInfoEnabled()) {
    68                             logger.info("Not allowed to obtain system environment variable [" + variableName + "]: " +
    69                                     ex.getMessage());
    70                         }
    71                         return null;
    72                     }
    73                 }
    74             };
    75         }
    76         beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
    77     }
    78 }

    首先是第3行,配置当前上下文ClassLoader

    接着是第4行,这是一个表达是语言处理器,可以使用#{bean.xxx}的方式来调用相关属性值

    接着是第5行,这是一个属性编辑器,具体没怎么用过

    接着是第8行,第8行增加了一个ApplicationContextAwareProcessor用于上下文回调,它是BeanPostProcessor的实现类,跟一下这个接口的两个方法postProcessBeforeInitialization和postProcessAfterInitialization即可知道这个方法的作用是:

    • 如果Bean是EmbeddedValueResolverAware接口的实现类,则调用setEmbeddedValueResolver方法,传入当前BeanFactory
    • 如果Bean是ResourceLoaderAware接口的实现类,则调用setResourceLoader方法,传入当前上下文ApplicationContext
    • 如果Bean是ApplicationEventPublisherAware的实现类,则调用setApplicationEventPublisher方法,传入当前上下文ApplicationContext
    • 如果Bean是MessageSourceAware的实现类,则调用setMessageSource方法,传入当前上下文ApplicationContext
    • 如果Bean是ApplicationContextAware的实现类,则调用setApplicationContext方法,传入当前上下文ApplicationContext

    接着是第9行~第12行,意思是Bean如果是这些接口的实现类,则不会被自动装配,自动装配见【Spring9】Autowire(自动装配)机制

    接着是第16行~第19行,意思是修正依赖,这里是一些自动装配的特殊规则,比如是BeanFactory接口的实现类,则修正为当前BeanFactory

    接着是第22行~第26行,意思是如果自定义的Bean中有定义过一个名为"loadTimeWeaver"的Bean,则会添加一个LoadTimeWeaverAwareProcessor

    最后是第29行~第77行,意思是如果自定义的Bean中没有名为"systemProperties"和"systemEnvironment"的Bean,则注册两个Bena,Key为"systemProperties"和"systemEnvironment",Value为Map,这两个Bean就是一些系统配置和系统环境信息,具体可以写这么一段代码测试一下:

    public class TestSpring {
        
        @SuppressWarnings("unchecked")
        @Test
        public void testSpring() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("spring/spring.xml");
            
            Map<String, String> systemPropertiesBean = (Map<String, String>)ac.getBean("systemProperties");
            for (Map.Entry<String, String> entry : systemPropertiesBean.entrySet()) {
                System.out.println(entry.getKey() + "--->" + entry.getValue());
            }
            
            System.out.println("==============================华丽的分隔符==============================");
            Map<String, String> systemEnvironmentBean = (Map<String, String>)ac.getBean("systemEnvironment");
            for (Map.Entry<String, String> entry : systemEnvironmentBean.entrySet()) {
                System.out.println(entry.getKey() + "--->" + entry.getValue());
            }
        }
        
    }

    涉及个人信息,运行结果我就不贴了,大家可以自己试试,至此整个PrepareBeanFactory方法的细节已经分析完毕了。

    invokeBeanFactoryPostProcessors方法

    这个是整个Spring流程中非常重要的一部分,是Spring留给用户的一个非常有用的扩展点,BeanPostProcessor接口针对的是每个Bean初始化前后做的操作而BeanFactoryPostProcessor接口针对的是所有Bean实例化前的操作,注意用词,初始化只是实例化的一部分,表示的是调用Bean的初始化方法,BeanFactoryPostProcessor接口方法调用时机是任意一个自定义的Bean被反射生成出来前

    OK,看一下源码:

     1 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
     2     // Invoke BeanDefinitionRegistryPostProcessors first, if any.
     3     Set<String> processedBeans = new HashSet<String>();
     4     if (beanFactory instanceof BeanDefinitionRegistry) {
     5         BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
     6         List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
     7         List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
     8                 new LinkedList<BeanDefinitionRegistryPostProcessor>();
     9         for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
    10             if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    11                 BeanDefinitionRegistryPostProcessor registryPostProcessor =
    12                             (BeanDefinitionRegistryPostProcessor) postProcessor;
    13                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
    14                     registryPostProcessors.add(registryPostProcessor);
    15             }
    16             else {
    17                 regularPostProcessors.add(postProcessor);
    18             }
    19         }
    20         Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
    21                 beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
    22         List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
    23                 new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
    24         OrderComparator.sort(registryPostProcessorBeans);
    25         for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
    26             postProcessor.postProcessBeanDefinitionRegistry(registry);
    27         }
    28         invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    29         invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
    30         invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    31         processedBeans.addAll(beanMap.keySet());
    32     }
    33     else {
    34         // Invoke factory processors registered with the context instance.
    35         invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
    36     }
    37 
    38     // Do not initialize FactoryBeans here: We need to leave all regular beans
    39     // uninitialized to let the bean factory post-processors apply to them!
    40     String[] postProcessorNames =
    41         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    42 
    43     // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    44     // Ordered, and the rest.
    45     List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    46     List<String> orderedPostProcessorNames = new ArrayList<String>();
    47     List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    48     for (String ppName : postProcessorNames) {
    49         if (processedBeans.contains(ppName)) {
    50             // skip - already processed in first phase above
    51         }
    52         else if (isTypeMatch(ppName, PriorityOrdered.class)) {
    53             priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    54         }
    55         else if (isTypeMatch(ppName, Ordered.class)) {
    56             orderedPostProcessorNames.add(ppName);
    57         }
    58         else {
    59             nonOrderedPostProcessorNames.add(ppName);
    60         }
    61     }
    62 
    63     // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    64     OrderComparator.sort(priorityOrderedPostProcessors);
    65     invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    66 
    67     // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    68     List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    69     for (String postProcessorName : orderedPostProcessorNames) {
    70         orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    71     }
    72     OrderComparator.sort(orderedPostProcessors);
    73     invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    74 
    75     // Finally, invoke all other BeanFactoryPostProcessors.
    76     List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    77     for (String postProcessorName : nonOrderedPostProcessorNames) {
    78         nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    79     }
    80     invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    81 }

    我们可以自己实现BeanFactoryPostProcessor接口并实现postProcessBeanFactory方法,在所有Bean加载的流程开始前,会调用一次postProcessBeanFactory方法。分析一下这段代码,首先我们使用的是DefaultListableBeanFactory,它是BeanDefinitionRegistry的子类,因此进入第4行的判断。

    整个判断获取的是当前有的BeanFactoryPostProcessor并调用postProcessBeanFactory,这些BeanFactoryPostProcessor是前置通过AbstractApplicationContext的addBeanFactoryPostProcessor方法添加的而不是配置文件里面配置的BeanFactoryPostProcessor的实现Bean,因此这个判断没有任何可执行的BeanFactoryPostProcessor。

    接着40行~41行这两行,获取的是beanDefinitionMap中的Bean,即用户自定义的Bean。

    接着第45行~61行,这里分出了三个List,表示开发者可以自定义BeanFactoryPostProcessor的调用顺序,具体为调用顺序为:

    • 如果BeanFactoryPostProcessor实现了PriorityOrdered接口(PriorityOrdered接口是Ordered的子接口,没有自己的接口方法定义,只是做一个标记,表示调用优先级高于Ordered接口的子接口),是优先级最高的调用,调用顺序是按照接口方法getOrder()的实现,对返回的int值从小到大进行排序,进行调用
    • 如果BeanFactoryPostProcessor实现了Ordered接口,是优先级次高的调用,将在所有实现PriorityOrdered接口的BeanFactoryPostProcessor调用完毕之后,依据getOrder()的实现对返回的int值从小到大排序,进行调用
    • 不实现Ordered接口的BeanFactoryPostProcessor在上面的BeanFactoryPostProcessor调用全部完毕之后进行调用,调用顺序就是Bean定义的顺序

    最后的第63行~第80行就是按照上面的规则依次先将BeanFactoryPostProcessor接口对应的实现类实例化出来并调用postProcessBeanFactory方法。

    registerBeanPostProcessors方法

    接下来看看registerBeanPostProcessors方法,顾名思义,就是注册自定义的BeanPostProcessor接口。看一下代码实现:

     1 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
     2     String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
     3 
     4     // Register BeanPostProcessorChecker that logs an info message when
     5     // a bean is created during BeanPostProcessor instantiation, i.e. when
     6     // a bean is not eligible for getting processed by all BeanPostProcessors.
     7     int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
     8     beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
     9 
    10     // Separate between BeanPostProcessors that implement PriorityOrdered,
    11     // Ordered, and the rest.
    12     List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    13     List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    14     List<String> orderedPostProcessorNames = new ArrayList<String>();
    15     List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    16     for (String ppName : postProcessorNames) {
    17         if (isTypeMatch(ppName, PriorityOrdered.class)) {
    18             BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    19             priorityOrderedPostProcessors.add(pp);
    20             if (pp instanceof MergedBeanDefinitionPostProcessor) {
    21                 internalPostProcessors.add(pp);
    22             }
    23         }
    24         else if (isTypeMatch(ppName, Ordered.class)) {
    25             orderedPostProcessorNames.add(ppName);
    26         }
    27         else {
    28             nonOrderedPostProcessorNames.add(ppName);
    29         }
    30     }
    31 
    32     // First, register the BeanPostProcessors that implement PriorityOrdered.
    33     OrderComparator.sort(priorityOrderedPostProcessors);
    34     registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    35 
    36     // Next, register the BeanPostProcessors that implement Ordered.
    37     List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    38     for (String ppName : orderedPostProcessorNames) {
    39         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    40         orderedPostProcessors.add(pp);
    41         if (pp instanceof MergedBeanDefinitionPostProcessor) {
    42             internalPostProcessors.add(pp);
    43         }
    44     }
    45     OrderComparator.sort(orderedPostProcessors);
    46     registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    47 
    48     // Now, register all regular BeanPostProcessors.
    49     List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    50     for (String ppName : nonOrderedPostProcessorNames) {
    51         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    52         nonOrderedPostProcessors.add(pp);
    53         if (pp instanceof MergedBeanDefinitionPostProcessor) {
    54             internalPostProcessors.add(pp);
    55         }
    56     }
    57     registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    58 
    59     // Finally, re-register all internal BeanPostProcessors.
    60     OrderComparator.sort(internalPostProcessors);
    61     registerBeanPostProcessors(beanFactory, internalPostProcessors);
    62 
    63     beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
    64 }

    整体代码思路和invokeBeanFactoryPostProcessors方法类似,但是这里不会调用BeanPostProcessor接口的方法,而是把每一个BeanPostProcessor接口实现类实例化出来并按照顺序放入一个List中,到时候按顺序进行调用。

    具体代码思路可以参考invokeBeanFactoryPostProcessors,这里就根据代码总结一下BeanPostProcessor接口的调用顺序:

    • 优先调用PriorityOrdered接口的子接口,调用顺序依照接口方法getOrder的返回值从小到大排序
    • 其次调用Ordered接口的子接口,调用顺序依照接口方法getOrder的返回值从小到大排序
    • 接着按照BeanPostProcessor实现类在配置文件中定义的顺序进行调用
    • 最后调用MergedBeanDefinitionPostProcessor接口的实现Bean,同样按照在配置文件中定义的顺序进行调用

    initMessageSource方法

    initMessageSource方法用于初始化MessageSource,MessageSource是Spring定义的用于实现访问国际化的接口,看一下源码:

     1 protected void initMessageSource() {
     2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     3     if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
     4         this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
     5         // Make MessageSource aware of parent MessageSource.
     6         if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
     7             HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
     8             if (hms.getParentMessageSource() == null) {
     9                 // Only set parent context as parent MessageSource if no parent MessageSource
    10                 // registered already.
    11                 hms.setParentMessageSource(getInternalParentMessageSource());
    12             }
    13         }
    14         if (logger.isDebugEnabled()) {
    15             logger.debug("Using MessageSource [" + this.messageSource + "]");
    16         }
    17     }
    18     else {
    19         // Use empty MessageSource to be able to accept getMessage calls.
    20         DelegatingMessageSource dms = new DelegatingMessageSource();
    21         dms.setParentMessageSource(getInternalParentMessageSource());
    22         this.messageSource = dms;
    23             beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    24         if (logger.isDebugEnabled()) {
    25             logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
    26                     "': using default [" + this.messageSource + "]");
    27         }
    28     }
    29 }

    这个if...else...判断比较好理解:

    • 如果自定义了名为"messageSource"的Bean,那么直接实例化Bean,该Bean必须是MessageSource接口的实现Bean,顺便该Bean如果是HierarchicalMessageSource接口的实现类,强转为HierarchicalMessageSource接口,并设置一下parentMessageSource
    • 如果没有自定义名为"messageSource"的Bean,那么会默认注册一个DelegatingMessageSource并加入

    initApplicationEventMulticaster方法

    initApplicationEventMulticaster方法是用于初始化上下文事件广播器的,看一下源码:

     1 protected void initApplicationEventMulticaster() {
     2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     3     if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
     4         this.applicationEventMulticaster =
     5                 beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
     6         if (logger.isDebugEnabled()) {
     7             logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
     8         }
     9     }
    10     else {
    11         this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    12         beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    13         if (logger.isDebugEnabled()) {
    14             logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
    15                     APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
    16                     "': using default [" + this.applicationEventMulticaster + "]");
    17         }
    18     }
    19 }

    和initMessageSource方法一样,这个if...else...判断也比较好理解:

    • 如果自定义了名为"applicationEventMulticaster"的Bean,就实例化自定义的Bean,但自定义的Bean必须是ApplicationEventMulticaster接口的实现类
    • 如果没有自定义名为"ApplicationEventMulticaster"的Bean,那么就注册一个类型为SimpleApplicationEventMulticaster的Bean

    整个Spring的广播器是观察者模式的经典应用场景之一,这个之后有时间会分析Spring广播器的源码。

    onRefresh方法

    接下来简单说说onRefresh方法,AbstractApplicationContext中这个方法没有什么定义:

    /**
     * Template method which can be overridden to add context-specific refresh work.
     * Called on initialization of special beans, before instantiation of singletons.
     * <p>This implementation is empty.
     * @throws BeansException in case of errors
     * @see #refresh()
     */
    protected void onRefresh() throws BeansException {
        // For subclasses: do nothing by default.
    }

    看一下注释的意思:一个模板方法,重写它的作用是添加特殊上下文刷新的工作,在特殊Bean的初始化时、初始化之前被调用。在Spring中,AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext都实现了这个方法。

    registerListeners方法

    registerListeners方法顾名思义,用于注册监听器:

     1 /**
     2  * Add beans that implement ApplicationListener as listeners.
     3  * Doesn't affect other listeners, which can be added without being beans.
     4  */
     5 protected void registerListeners() {
     6     // Register statically specified listeners first.
     7     for (ApplicationListener listener : getApplicationListeners()) {
     8         getApplicationEventMulticaster().addApplicationListener(listener);
     9     }
    10     // Do not initialize FactoryBeans here: We need to leave all regular beans
    11     // uninitialized to let post-processors apply to them!
    12     String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    13     for (String lisName : listenerBeanNames) {
    14         getApplicationEventMulticaster().addApplicationListenerBean(lisName);
    15     }
    16 }

    这里先向applicationEventMulticaster中注册一些静态的、特定的监听器。

    finishRefresh方法

    最后一步,结束Spring上下文刷新:

     1 /**
     2  * Finish the refresh of this context, invoking the LifecycleProcessor's
     3  * onRefresh() method and publishing the
     4  * {@link org.springframework.context.event.ContextRefreshedEvent}.
     5  */
     6 protected void finishRefresh() {
     7     // Initialize lifecycle processor for this context.
     8     initLifecycleProcessor();
     9 
    10     // Propagate refresh to lifecycle processor first.
    11     getLifecycleProcessor().onRefresh();
    12 
    13     // Publish the final event.
    14     publishEvent(new ContextRefreshedEvent(this));
    15 }

    这里面分了三步,第一步,初始化LifecycleProcessor接口:

     1 protected void initLifecycleProcessor() {
     2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     3     if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
     4         this.lifecycleProcessor =
     5                 beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
     6         if (logger.isDebugEnabled()) {
     7             logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
     8         }
     9     }
    10     else {
    11         DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
    12         defaultProcessor.setBeanFactory(beanFactory);
    13         this.lifecycleProcessor = defaultProcessor;
    14         beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
    15         if (logger.isDebugEnabled()) {
    16             logger.debug("Unable to locate LifecycleProcessor with name '" +
    17                     LIFECYCLE_PROCESSOR_BEAN_NAME +
    18                     "': using default [" + this.lifecycleProcessor + "]");
    19         }
    20     }
    21 }

    流程和initMessageSource方法、initApplicationEventMulticaster方法基本类似:

    • 先找一下有没有自定义名为"lifecycleProcessor"的Bean,有的话就实例化出来,该Bean必须是LifecycleProcessor的实现类
    • 没有自定义名为"lifecycleProcessor"的Bean,向Spring上下文中注册一个类型为DefaultLifecycleProcessor的LifecycleProcessor实现类

    第二步,调用一下LifecycleProcessor的onRefresh方法。

    第三步,由于之前已经初始化了:

     1 public void publishEvent(ApplicationEvent event) {
     2     Assert.notNull(event, "Event must not be null");
     3     if (logger.isTraceEnabled()) {
     4         logger.trace("Publishing event in " + getDisplayName() + ": " + event);
     5     }
     6     getApplicationEventMulticaster().multicastEvent(event);
     7     if (this.parent != null) {
     8         this.parent.publishEvent(event);
     9     }
    10 }

    后记

    再看AbstractApplicationContext的refresh方法,从中读到了很多细节:

    • Spring默认加载的两个Bean,systemProperties和systemEnvironment,分别用于获取环境信息、系统信息
    • BeanFactoryPostProcessor接口用于在所有Bean实例化之前调用一次postProcessBeanFactory
    • 可以通过实现PriorityOrder、Order接口控制BeanFactoryPostProcessor调用顺序
    • 可以通过实现PriorityOrder、Order接口控制BeanPostProcessor调用顺序
    • 默认的MessageSource,名为"messageSource"
    • 默认的ApplicationEventMulticaster,名为"applicationEventMulticaster"
    • 默认的LifecycleProcessor,名为"lifecycleProcessor"

    除了这些,在整个refresh方法里还隐藏了许多细节,这里就不一一罗列了,多读源码,会帮助我们更好地使用Spring。

  • 相关阅读:
    Spark Steaming消费kafka数据条数变少问题
    intellij idea 搜索
    ZooKeeper shell
    linux 端口映射设置
    maxCompute odps 行转列
    dev stg prd 开发 测试 生产环境
    大数据之路
    MYSQL性能优化
    JavaScript学习笔记-setTimeout应用
    JavaScript学习笔记-函数
  • 原文地址:https://www.cnblogs.com/xrq730/p/6670457.html
Copyright © 2020-2023  润新知