之前的随笔中借BeanFactory介绍了bean的解析和加载的完整过程,实际上,除了BeanFactory,spring还提供了一种功能更加强大的容器:ApplicationContext

ApplicationContext不但具备了BeanFactory的完整功能,还提供了一些扩展功能。因此,除非是在一些限制场合下,spring通常建议我们使用ApplicationContext这一容器。

我们首先进入到ClassPathXmlApplicationContext的构造函数中

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if(refresh) {
            this.refresh();
        }

    }

这里简单调用了父类的构造函数,并且设置了配置的位置,具体的逻辑在refresh()方法中

 

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if(this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

这个方法写的还是比较整洁的,我们一个一个方法来看

首先是prepareRefresh()

protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if(this.logger.isInfoEnabled()) {
            this.logger.info("Refreshing " + this);
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        this.earlyApplicationEvents = new LinkedHashSet();
    }

这里的逻辑十分简单,做了一些环境的初始化操作,值得一提的是这里的initPropertySources()方法,如果点开这个方法的话,我们会发现这个方法的方法体是空的。说明这个方法是为了支持扩展用的,当我们想要在容器启动前做一些特殊操作时,例如做一些依赖的校验,如果没有校验通过,那么可以直接停止启动容器。如果想要做这个特殊处理,只需要继承一下这个容器,并重写一下这个方法就可以了。从这里我们也可以看到spring支持扩展方面做得还是很好的。

 

 接下来我们来看obtainFreshBeanFactory()

ApplicationContext之所以能包含BeanFactory的所有功能,就是在这里实现的。实现的具体逻辑在refreshBeanFactory方法中。

protected final void refreshBeanFactory() throws BeansException {
        if(this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            DefaultListableBeanFactory ex = this.createBeanFactory();
            ex.setSerializationId(this.getId());
            this.customizeBeanFactory(ex);
            this.loadBeanDefinitions(ex);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = ex;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

简单的说就是,ApplicationContext中持有了一个DefaultListableBeanFactory(也就是BeanFactory的父类)的一个全局变量,在这个方法中主要做了几件事情:

1、创建DefaultListableBeanFactory

2、指定序列化ID

3、定制Beanfactory

4、加载BeaDefinition

5、使用全局变量记录BeanFactory类实例。

 

到这里位置,ApplicationContext已经包含了BeanFactory的完整功能了,接下来就是ApplicationContext的扩展功能了。

我们进入到prepareBeanFactory中

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        if(beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if(!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if(!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if(!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

1、增加SPEL语言支持

首先在

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

ApplicationContext注册了语言解析器,这个解析器支持容器对SPEL语言提供了支持。

所谓的SPEL语言就是使用#{...}作为定界符,大括号里的就是spel

例如

<bean id="normalUser" class="com.wuzhe.spring.test.UserFactory" factory-method="getUser"/>
    <bean id="admin" class="com.wuzhe.spring.test.User">
        <property name="user" value="#{normalUser}"></property>
    </bean>

其实就相当于

<bean id="normalUser" class="com.wuzhe.spring.test.UserFactory" factory-method="getUser"/>
    <bean id="admin" class="com.wuzhe.spring.test.User">
        <property name="user" ref="normalUser"></property>
    </bean>

使用好这个语言可以提高开发效率。

2、增加属性注册编辑器

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));

 这个方法本身并没有什么好说的,只是简单注册了ResourceEditorRegistrer

更重要的方法实际上是

public void registerCustomEditors(PropertyEditorRegistry registry) {
        ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
        this.doRegisterEditor(registry, Resource.class, baseEditor);
        this.doRegisterEditor(registry, ContextResource.class, baseEditor);
        this.doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
        this.doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
        this.doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
        if(pathClass != null) {
            this.doRegisterEditor(registry, pathClass, new PathEditor(baseEditor));
        }

        this.doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
        this.doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
        ClassLoader classLoader = this.resourceLoader.getClassLoader();
        this.doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
        this.doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
        this.doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
        if(this.resourceLoader instanceof ResourcePatternResolver) {
            this.doRegisterEditor(registry, Resource[].class, new ResourceArrayPropertyEditor((ResourcePatternResolver)this.resourceLoader, this.propertyResolver));
        }

    }

    private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
        if(registry instanceof PropertyEditorRegistrySupport) {
            ((PropertyEditorRegistrySupport)registry).overrideDefaultEditor(requiredType, editor);
        } else {
            registry.registerCustomEditor(requiredType, editor);
        }

    }

在这里我们可以实现自定义的属性编辑器。

我们知道在Spring DI的时候会将普通的属性注入到bean中,但只支持一些类型,像Date类型就无法被识别出来,这时候就可以通过

 1)定义属性编辑器

public class DatePropertyEditor  implements PropertyEditorRegistrar {


    public void registerCustomEditors(PropertyEditorRegistry propertyEditorRegistry) {
        propertyEditorRegistry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("YYYY-MM-dd"), true));
    }
}

2)注册到Spring中

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="propertyEditorRegistrars">
            <list>
                <bean class="com.wuzhe.spring.test.DatePropertyEditor"></bean>
            </list>
        </property>
    </bean>

这样就可以实现解析String为Date类型,并注入到Bean中

 

3、添加ApplicationContextAwareProcessor处理器

接下来这条

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

这里注册了BeanPostProcessor,我们知道在BeanFactory实例化Bean之后,在调用init-method左右会依次调用所有注册的BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法

这里注册的BeanPostProcessor主要干了一件事情,我们从ApplicationContextAwareProcessor的postProcessBeforeInitialization可以看出

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;
        if(System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if(acc != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
                    return null;
                }
            }, acc);
        } else {
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if(bean instanceof Aware) {
            if(bean instanceof EnvironmentAware) {
                ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
            }

            if(bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }

            if(bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if(bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
            }

            if(bean instanceof MessageSourceAware) {
                ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
            }

            if(bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

    }

 这里对于实现了Aware接口的bean,在实例化之后会获得相应的一些资源。这个扩展挺有用的,例如在SpringMVC中,我想要拿到应用启动时加载的容器ApplicationContext,那么我就可以让某个bean继承ApplicationContextAware接口,这样这个bean就能拿到当前的容器了,接下来就可以使用这个容器做一些自定义的业务逻辑。

 

看完了prepareBeanFactory()接下来是

this.postProcessBeanFactory(beanFactory);

这里面是一段空代码,spring为了支持扩展,可以通过重写这个方法,实现BeanFactory的后处理。

 

再来看,还有一种方式可以实现BeanFactory的后处理

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        HashSet processedBeans = new HashSet();
        int postProcessorName;
        ArrayList var20;
        ArrayList var23;
        if(beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry postProcessorNames = (BeanDefinitionRegistry)beanFactory;
            LinkedList priorityOrderedPostProcessors = new LinkedList();
            LinkedList orderedPostProcessorNames = new LinkedList();
            Iterator nonOrderedPostProcessorNames = beanFactoryPostProcessors.iterator();

            while(nonOrderedPostProcessorNames.hasNext()) {
                BeanFactoryPostProcessor orderedPostProcessors = (BeanFactoryPostProcessor)nonOrderedPostProcessorNames.next();
                if(orderedPostProcessors instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor nonOrderedPostProcessors = (BeanDefinitionRegistryPostProcessor)orderedPostProcessors;
                    nonOrderedPostProcessors.postProcessBeanDefinitionRegistry(postProcessorNames);
                    orderedPostProcessorNames.add(nonOrderedPostProcessors);
                } else {
                    priorityOrderedPostProcessors.add(orderedPostProcessors);
                }
            }

            String[] var18 = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var20 = new ArrayList();
            String[] var22 = var18;
            postProcessorName = var18.length;

            int postProcessorName1;
            for(postProcessorName1 = 0; postProcessorName1 < postProcessorName; ++postProcessorName1) {
                String ppName = var22[postProcessorName1];
                if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    var20.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(beanFactory, var20);
            orderedPostProcessorNames.addAll(var20);
            invokeBeanDefinitionRegistryPostProcessors(var20, postProcessorNames);
            var18 = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var23 = new ArrayList();
            String[] var26 = var18;
            postProcessorName1 = var18.length;

            int var30;
            for(var30 = 0; var30 < postProcessorName1; ++var30) {
                String ppName1 = var26[var30];
                if(!processedBeans.contains(ppName1) && beanFactory.isTypeMatch(ppName1, Ordered.class)) {
                    var23.add(beanFactory.getBean(ppName1, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName1);
                }
            }

            sortPostProcessors(beanFactory, var23);
            orderedPostProcessorNames.addAll(var23);
            invokeBeanDefinitionRegistryPostProcessors(var23, postProcessorNames);
            boolean var27 = true;

            while(var27) {
                var27 = false;
                var18 = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                String[] var28 = var18;
                var30 = var18.length;

                for(int var33 = 0; var33 < var30; ++var33) {
                    String ppName2 = var28[var33];
                    if(!processedBeans.contains(ppName2)) {
                        BeanDefinitionRegistryPostProcessor pp = (BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName2, BeanDefinitionRegistryPostProcessor.class);
                        orderedPostProcessorNames.add(pp);
                        processedBeans.add(ppName2);
                        pp.postProcessBeanDefinitionRegistry(postProcessorNames);
                        var27 = true;
                    }
                }
            }

            invokeBeanFactoryPostProcessors((Collection)orderedPostProcessorNames, (ConfigurableListableBeanFactory)beanFactory);
            invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }

        String[] var15 = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        ArrayList var16 = new ArrayList();
        ArrayList var17 = new ArrayList();
        ArrayList var19 = new ArrayList();
        String[] var21 = var15;
        int var24 = var15.length;

        String var29;
        for(postProcessorName = 0; postProcessorName < var24; ++postProcessorName) {
            var29 = var21[postProcessorName];
            if(!processedBeans.contains(var29)) {
                if(beanFactory.isTypeMatch(var29, PriorityOrdered.class)) {
                    var16.add(beanFactory.getBean(var29, BeanFactoryPostProcessor.class));
                } else if(beanFactory.isTypeMatch(var29, Ordered.class)) {
                    var17.add(var29);
                } else {
                    var19.add(var29);
                }
            }
        }

        sortPostProcessors(beanFactory, var16);
        invokeBeanFactoryPostProcessors((Collection)var16, (ConfigurableListableBeanFactory)beanFactory);
        var20 = new ArrayList();
        Iterator var25 = var17.iterator();

        while(var25.hasNext()) {
            String var31 = (String)var25.next();
            var20.add(beanFactory.getBean(var31, BeanFactoryPostProcessor.class));
        }

        sortPostProcessors(beanFactory, var20);
        invokeBeanFactoryPostProcessors((Collection)var20, (ConfigurableListableBeanFactory)beanFactory);
        var23 = new ArrayList();
        Iterator var32 = var19.iterator();

        while(var32.hasNext()) {
            var29 = (String)var32.next();
            var23.add(beanFactory.getBean(var29, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)var23, (ConfigurableListableBeanFactory)beanFactory);
        beanFactory.clearMetadataCache();
    }

这段代码比较长,但总的来说这个方法实现的功能就是一个:找到BeanFactoryPostProcessor,并调用它的后处理方法。

这里把BeanFactoryPostProcessor分成了三类:

1)通过硬编码的方式注册在容器中的BeanDefinitionRegistryPostProcessor

2)通过硬编码的方式注册在容器中的BeanFactoryPostProcessor

3)  配置中的BeanFactoryPostProcessor bean

分别读取这三类之后,这个方法会对BeanFactoryPostProcessor 进行排序,排序的依据是这个bean是否继承了PriorityOrdered或是Ordered的getOrder()方法,如果getOrder方法返回的int值越大,则这个处理器的排序更靠前,排序完后,spring就会依次调用处理器的方法。

这一功能可扩展性非常强,可以让我们在BeanFactory解析好配置文件之后,灵活地改变容器中的配置例如BeanDefinition等,像之前介绍的自定义属性编辑器的注册也是一种BeanFactoryPostProcessor,通过这一功能我们还可以对配置中一些属性进行过滤或是做特殊处理。

 

当所有BeanFactoryPostProcessor处理完之后,接下来spring会注册BeanPostProcessor,BeanPostProcessor会在bean实例化后,init-method前后被调用。看一下注册代码

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
        ArrayList priorityOrderedPostProcessors = new ArrayList();
        ArrayList internalPostProcessors = new ArrayList();
        ArrayList orderedPostProcessorNames = new ArrayList();
        ArrayList nonOrderedPostProcessorNames = new ArrayList();
        String[] orderedPostProcessors = postProcessorNames;
        int nonOrderedPostProcessors = postProcessorNames.length;

        String ppName1;
        BeanPostProcessor pp;
        for(int ppName = 0; ppName < nonOrderedPostProcessors; ++ppName) {
            ppName1 = orderedPostProcessors[ppName];
            if(beanFactory.isTypeMatch(ppName1, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName1, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if(pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if(beanFactory.isTypeMatch(ppName1, Ordered.class)) {
                orderedPostProcessorNames.add(ppName1);
            } else {
                nonOrderedPostProcessorNames.add(ppName1);
            }
        }

        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        ArrayList var13 = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();

        while(var14.hasNext()) {
            String var16 = (String)var14.next();
            BeanPostProcessor var18 = (BeanPostProcessor)beanFactory.getBean(var16, BeanPostProcessor.class);
            var13.add(var18);
            if(var18 instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(var18);
            }
        }

        sortPostProcessors(beanFactory, var13);
        registerBeanPostProcessors(beanFactory, (List)var13);
        ArrayList var15 = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();

        while(var17.hasNext()) {
            ppName1 = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName1, BeanPostProcessor.class);
            var15.add(pp);
            if(pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        registerBeanPostProcessors(beanFactory, (List)var15);
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

这里spring的处理方式和处理BeanFactoryPostProcessor极为相似,连排序的接口也是一样的,区别就是

这里只需将BeanPostProcessor分为两种情况:

1)硬编码的BeanPostProcessor

2) 配置文件中的BeanPostProcessor

拿到所有的BeanPostProcess然后分别排序,最后注册到容器中。

 

说完了BeanPostProcessor,接下来说一下Spring的事件监听。Spring可以通过注册监听器,对容器中的事件监听并实现用户自定义的业务逻辑。

首先Spring会初始化ApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
            }
        }

    }

这段代码的逻辑比较清晰,无非就是如果用户在容器中实现了自定义的事件广播器的话,就使用用户的自定义事件广播器;如果没有,那么Spring会使用默认的事件广播器SimpleApplicationEventMulticaster

我们走到这个类中去看一下这个广播器的实现机制

 

public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
        Iterator var4 = this.getApplicationListeners(event, type).iterator();

        while(var4.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var4.next();
            Executor executor = this.getTaskExecutor();
            if (executor != null) {
                executor.execute(() -> {
                    this.invokeListener(listener, event);
                });
            } else {
                this.invokeListener(listener, event);
            }
        }

    }

 

在SimpleApplicationEventMulticaster类的multicastEvent方法中可以看出Spring默认广播器的实现机制:

首先Spring会在内存中缓存所有的监听器,以Map的形式,key为监听事件和事件的source类型,value就是对应的监听器列表。

在getApplicationListeners方法中,Spring可以拿到所有属于当前时间的监听器。

然后遍历所有监听器,并调用监听器的接口,也就是ApplicationListener接口的onApplicationEvent()方法。

 

接下来this.onRefresh()这个方法又是一个空的方法,为了方便扩展。

到了registerListeners()这个方法,这个方法就是实现注册监听器。

 

protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();

        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }

 

可以看到同之前说的后处理器一样,Spring在这里也先考虑注册了硬编码实现的监听器,然后再对容器中配置文件中定义的所有实现ApplicationListener接口的bean一一注册到广播器中。

然后对一些容器中的earlyApplicationEvents做广播。

 

就这样到了ApplicationContext容器初始化的尾声了。

this.finishBeanFactoryInitialization(beanFactory);
在这个方法里主要实现了一些初始化非延迟加载单例的工作,这边就不一一赘述了
this.finishRefresh();
在这个方法里,Spring会广播ContextRefreshedEvent事件,说明容器初始化已经完成了。

 

容器的初始化就到这了结束了,至于ApplicationContext是如何获取bean的呢?

public Object getBean(String name) throws BeansException {
        this.assertBeanFactoryActive();
        return this.getBeanFactory().getBean(name);
    }

从上面这段代码中可以看出,ApplicationContext获取bean的方式完全和BeanFactory一致。之前的随笔已经讲过了,这边就不在重复了。