spring源码学习三:容器的创建流程

1 前言

spring提供了一个接口ApplicationContext,其作用和BeanFactory一样,都是用于加载bean。比如我们在测试类中启动spring的时候,常见的AnnotationConfigApplicationContext类,就实现了这个接口。在我个人目前的理解中,ApplicationContext可以指代spring容器。所以,容器的创建过程,就是创建一个ApplicationContext的过程。

本文大部分内容都是参考了《spring 源码深度解析》一书,喜欢的可以买来看看!

2 容器的创建概览

2.1 创建的入口

这里放一个普通的spring测试类,代码如下:

	@Test
    public void test1(){
        ApplicationContext app = new AnnotationConfigApplicationContext(配置类.class);
    }

这段代码的含义,就是创建spring容器,只不过是需要从配置类中加载配置。进入这个构造方法,其代码如下:

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }

这里的重头戏,便是**this.refresh()**方法了,在它里面完成了ApplicationContext几乎所有的功能。而且这一段代码写的很优秀,值得反复琢磨。这也是我学源码的时候很喜欢的一段了,逻辑很清晰,没有那种突然一大段代码扑到脸上的不知所措感,虽然刚开始看的时候根本不知道每个方法都在搞什么。

2.2 refresh()方法源码

refresh()方法源码和每个方法的注释如下:

	public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
        
        	//准备刷新的上下文环境
            this.prepareRefresh();

			//初始化BeanFactory,并且读取配置
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

			//对BeanFactory做功能的补充和完善
            this.prepareBeanFactory(beanFactory);

            try {
            	//留给子类去扩展的
                this.postProcessBeanFactory(beanFactory);
				
				//注册和调用BeanFactoryPostProcessor,从而对BeanFactory做后置处理
                this.invokeBeanFactoryPostProcessors(beanFactory);

				//注册BeanPostProcessor,注意仅仅是注册,而且是用来处理Bean的
                this.registerBeanPostProcessors(beanFactory);
				
				//为上下文初始化Message源,即不同语言的消息体,国际化处理
                this.initMessageSource();

				//初始化广播器
                this.initApplicationEventMulticaster();

				//留给子类重写,来初始化其他的bean。springboot内置的tomcat启动就和这个方法有关
                this.onRefresh();

				//从所有bean中找出Listener,并注册到广播器
                this.registerListeners();

				//初始化非懒加载的单例bean
                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();
            }

        }
    }

3 详细分析

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

3.2 obtainFreshBeanFactory():获取BeanFactory,加载配置

方法名直译过来,获得新鲜的BeanFactory。其实就是对BeanFactory进行创建,刚刚创建,所以比较新鲜。
源码如下:

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	
		//初始化BeanFactory,读取配置,并将BeanFactory保存在当前类的属性中
        this.refreshBeanFactory();
        
        //从当前类的属性中拿到BeanFactory
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }

在以上代码中,核心部分是refreshBeanFactory。

重写refreshBeanFactory方法的子类有两个,AbstractRefreshableApplicationContext和GenericApplicationContext。

在new AnnotationConfigApplicationContext(配置类.class)时,由于启动类AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以如果跑的是最上面的示例测试类时,运行的是GenericApplicationContext重写的refreshBeanFactory。

但是由于GenericApplicationContext重写的方法很简单,即直接反序列化得到BeanFactory对象,所以这里看的是AbstractRefreshableApplicationContext中重写的方法,这里较为详细,可以学到更多spring源码的精髓。

这里进入其子类AbstractRefreshableApplicationContext中重写的方法中看看。其源码如下

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

        try {
        	//创建DefaultListableBeanFactory 
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            
            //指定序列化id,如果需要,给以反序列化得到DefaultListableBeanFactory 
            beanFactory.setSerializationId(this.getId());
            
            //定制BeanFactory
            this.customizeBeanFactory(beanFactory);
            
            //加载配置
            this.loadBeanDefinitions(beanFactory);
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

从上面这段源码来看,其实其主要工作就三步,1 创建BeanFactory,2 定制BeanFactory,3 加载配置。

3.2.1 创建BeanFactory

	protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
    }

其实就是简单的调用了构造方法。

3.2.2 定制BeanFactory

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        
		//是否允许循环依赖
        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }

    }

3.2.3 加载配置

加载配置文件,需要两个类,分别是DefaultListableBeanFactory 和 XmlBeanDefinitionReader,前者已经在3.2.1创建BeanFactory时拿到了,在前面createBeanFactory方法中已经创建了,那么就需要生成后者。

	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	
		//利用DefaultListableBeanFactory 生成 XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        
		//加载配置文件
        this.loadBeanDefinitions(beanDefinitionReader);
    }

通过上面的操作,此时容器中已经解析了所有的配置。

3.3 prepareBeanFactory(beanFactory):BeanFactory的功能扩展

解析完了配置,创建了BeanFactory,接下来就是对BeanFactory的完善了。其源码如下:

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        
        //设置表达式解析器,这里的表达式就是 #{xxxx.xxx}
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        
        //增加PropertyEditor,对bean的属性进行设置,PropertyEditor可以理解为一种转换器,比如对Date的转换器,部分就在这里添加
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        
		//添加BeanPostProcessor
        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);
        
        //添加BeanPostProcessor
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        
        //对AspectJ的支持
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
		
		//添加默认的系统环境bean
        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());
        }

    }

3.3.1 spEL的支持

spEL,全称spring expression language。

spEL用法:#{xxx.xxx},例如#{person.name}。实际上spEL的用法有很多,而且很灵活,具体用法可以参考如下链接:

spEL的使用详解

注意:spEL中,#{}没有从properties中读取值的功能。${}才可以从properties中读取值,而且对于mybatis,不能防止sql注入,因为在mybatis中其作用为直接替换,不会解析,而是直接注入。#{}会进行解析,可以防止sql注入。

3.3.2 增加属性编辑器

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

spring在依赖注入的时候,有些属性其实并不能注入,常见的类型比如Date类型的属性,直接注入类似“2021-1-1”这样的日期,会报错。所以需要自定义属性编辑器。我们自己写的属性编辑器,和spring自带的属性编辑器,都会在这里被添加。

可以看一下被添加进BeanFactory的ResourceEditorRegistrar中的registerCustomEditors方法,如下所示,就是注册很多属性编辑器罢了。

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));
        this.doRegisterEditor(registry, Path.class, 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));
        }

    }

这里提个问,registerCustomEditors才是注册属性编辑器的方法,但是添加进BeanFactory的时候,没有调用registerCustomEditors,那么该方法在哪调用?

答:在如下方法中被调用。

	protected void initBeanWrapper(BeanWrapper bw) {
        bw.setConversionService(this.getConversionService());
        this.registerCustomEditors(bw);
    }

而initBeanWrapper----》被instantiateBean调用,instantiateBean—》被createBeanInstance调用,createBeanInstance—》被doCreateBean调用。

那么这里就显而易见了,这些属性编辑器,就是在实例化bean的时候注册的。

那么又有疑问,有没有觉得这里注册的属性编辑器还不够多呢,我们常用的Integer、Long等,好像并没有出现?

答:对于一个BeanWrapper,spring默认的实现为BeanWrapperImpl,而BeanWrapperImpl继承了PropertyEditorRegistrySupport。这个PropertyEditorRegistrySupport有个方法,如下所示:

	private void createDefaultEditors() {
        this.defaultEditors = new HashMap(64);
        this.defaultEditors.put(Charset.class, new CharsetEditor());
        this.defaultEditors.put(Class.class, new ClassEditor());
        this.defaultEditors.put(Class[].class, new ClassArrayEditor());
        this.defaultEditors.put(Currency.class, new CurrencyEditor());
        this.defaultEditors.put(File.class, new FileEditor());
        this.defaultEditors.put(InputStream.class, new InputStreamEditor());
        this.defaultEditors.put(InputSource.class, new InputSourceEditor());
        this.defaultEditors.put(Locale.class, new LocaleEditor());
        this.defaultEditors.put(Path.class, new PathEditor());
        this.defaultEditors.put(Pattern.class, new PatternEditor());
        this.defaultEditors.put(Properties.class, new PropertiesEditor());
        this.defaultEditors.put(Reader.class, new ReaderEditor());
        this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
        this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
        this.defaultEditors.put(URI.class, new URIEditor());
        this.defaultEditors.put(URL.class, new URLEditor());
        this.defaultEditors.put(UUID.class, new UUIDEditor());
        this.defaultEditors.put(ZoneId.class, new ZoneIdEditor());
        this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
        this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
        this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
        this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
        this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));
        this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
        this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());
        this.defaultEditors.put(Character.TYPE, new CharacterEditor(false));
        this.defaultEditors.put(Character.class, new CharacterEditor(true));
        this.defaultEditors.put(Boolean.TYPE, new CustomBooleanEditor(false));
        this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
        this.defaultEditors.put(Byte.TYPE, new CustomNumberEditor(Byte.class, false));
        this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
        this.defaultEditors.put(Short.TYPE, new CustomNumberEditor(Short.class, false));
        this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
        this.defaultEditors.put(Integer.TYPE, new CustomNumberEditor(Integer.class, false));
        this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
        this.defaultEditors.put(Long.TYPE, new CustomNumberEditor(Long.class, false));
        this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
        this.defaultEditors.put(Float.TYPE, new CustomNumberEditor(Float.class, false));
        this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
        this.defaultEditors.put(Double.TYPE, new CustomNumberEditor(Double.class, false));
        this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
        this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
        this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
        if (this.configValueEditorsActive) {
            StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
            this.defaultEditors.put(String[].class, sae);
            this.defaultEditors.put(short[].class, sae);
            this.defaultEditors.put(int[].class, sae);
            this.defaultEditors.put(long[].class, sae);
        }

    }

不管这个方法在哪调用的,至少知道了spring确实定义了很多属性编辑器。像Date类型,上面就没有,所以需要自己自定义。

3.3.3 添加ApplicationContextAwareProcessor处理器

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

其实在prepareBeanFactory中,就是单纯地把ApplicationContextAwareProcessor注册为BeanPostProcessor后置处理器。但是ApplicationContextAwareProcessor本身是一个很有作用处理器。

先看下这个类的继承和实现关系:

class ApplicationContextAwareProcessor implements BeanPostProcessor

既然实现了BeanPostProcessor,必然实现了BeanPostProcessor中的抽象方法,具体如下:

	@Nullable
    public Object postProcessBeforeInitialization(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(() -> {
                this.invokeAwareInterfaces(bean);
                return null;
            }, acc);
        } else {
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }
    
	public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }

从源码来看,重点就是postProcessBeforeInitialization方法。可以看到,方法中调用了invokeAwareInterfaces,跟进invokeAwareInterfaces中看到源码如下:

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

    }

可以看到方法里进行了类似switch似的的判断,如果满足条件则将某种功能赋予这个bean中。

再多留意一下可以发现,这些条件判断里的接口,都是***Aware这种格式。在spring中,以Aware结尾的接口,其作用是给bean中添加一些容器中的资源,例如:

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

就是给bean中注入spring容器。

3.3.4 设置依赖忽略

		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

为什么要设置忽略依赖?

首先,可以看出,这里忽略的,正是invokeAwareInterfaces()中出现的接口。

因为在3.3.3中invokeAwareInterfaces()方法中出现的这个接口,已经不能算作一个普通bean了。需要实现这些接口才可以使用接口提供的功能,而不是通过依赖注入的方式。

3.3.5 注册依赖

		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

与依赖忽略相反,依赖注册是当解析到bean需要注入以上这些类型的依赖时,便会将其注入。

3.4 invokeBeanFactoryPostProcessors(beanFactory):注册并激活BeanFactoryPostProcessor

源码如下:

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
		//注册并激活BeanFactoryPostProcessor
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

3.4.1 BeanFactoryPostProcessor的典型应用----》PropertyPlaceholderConfigurer

在dubbo项目中,可能会看到如下配置:

<dubbo:protocol host="${dubbo.ip}" name="dubbo" port="20886" />

不管这个duboo标签的意义是什么,单说${dubbo.ip},其意义就是去配置文件中读取dubbo.ip对应的值。在配置文件中,存在如下内容:

dubbo.ip=127.0.0.1

但是这里仍有问题,那就是spring怎么知道这里存在着待解析的配置文件呢?----》PropertyPlaceholderConfigurer

如下为PropertyPlaceholderConfigurer在配置文件中的配置方式:

	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:props/test1.properties</value>
                <value>classpath:props/test11.properties</value>
                <value>classpath:props/test111.properties</value>
                <value>classpath:props/test1111.properties</value>
            </list>
        </property>
    </bean>

这样便解决了上述问题。

PropertyPlaceholderConfigurer和BeanFactoryPostProcessor是什么关系呢?

这个关系其实蛮好找到,就是PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口。

这个接口长这样:

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

也就是说PropertyPlaceholderConfigurer实现了postProcessBeanFactory方法。

可是从配置来看,作为一个普通的bean,并没有被其他bean调用,那么spring怎么知道要在这个bean中有配置文件的信息呢?

因为其实现了BeanFactoryPostProcessor接口。

可以看下PropertyPlaceholderConfigurer的父类PropertyResourceConfigurer中实现的postProcessBeanFactory方法源码:

	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            Properties mergedProps = this.mergeProperties();
            this.convertProperties(mergedProps);
            this.processProperties(beanFactory, mergedProps);
        } catch (IOException var3) {
            throw new BeanInitializationException("Could not load properties", var3);
        }
    }

总结一下,这里做了三件事:
1 得到配置;
2 将得到的配置转换为适当的类型;
3 将配置告知beanFactory;

所以以上这个问题的答案就是,PropertyPlaceholderConfigurer作为一个BeanFactory的后置处理器,其重写的postProcessBeanFactory方法完成了从配置中读取配置文件信息的功能。

3.4.2 激活BeanFactoryPostProcessor

源码很长,但是仍有规律可循。以下为注释版源码:

    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        
		//对实现了BeanDefinitionRegistry的beanFactory的处理
		//顺带一提,spring默认的DefaultListableBeanFactory就实现了BeanDefinitionRegistry接口
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
            
            //拿到硬编码的beanFactoryPostProcessors
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                
                //判断后置处理器是否实现了BeanDefinitionRegistryPostProcessor接口
                //BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor什么关系?如下所示:
                //public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
                
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    
					//调用硬编码的BeanDefinitionRegistryPostProcessor类型处理器中的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                
                	//记录硬编码的常规BeanFactoryPostProcessor
                    regularPostProcessors.add(postProcessor);
                }
            }

            currentRegistryProcessors = new ArrayList();
            
            //从配置里拿BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var18 = postProcessorNames;
            var9 = postProcessorNames.length;
			
			//根据PriorityOrdered筛选从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
            int var10;
            String ppName;
            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var18[var10];
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            
            //激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            
			//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
            currentRegistryProcessors.clear();
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var18 = postProcessorNames;
            var9 = postProcessorNames.length;
			
			//根据Ordered筛选从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var18[var10];
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
			
			//激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

			//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
            currentRegistryProcessors.clear();
            boolean reiterate = true;

            while(reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                String[] var21 = postProcessorNames;
                var10 = postProcessorNames.length;
				//处理其余的从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
                for(int var28 = 0; var28 < var10; ++var28) {
                    String ppName = var21[var28];
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }

                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                
                //激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

				//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
                currentRegistryProcessors.clear();
            }
			
			//激活在**硬编码和配置**中,实现了**BeanDefinitionRegistryPostProcessor**的处理器中的postProcessBeanFactory方法,因为BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口
            invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
            
			//激活**硬编码**中,实现了**BeanFactoryPostProcessor**的类中的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }
		
		//从**配置**中拿到实现了BeanFactoryPostProcessor接口的类
		//类似上面的结构,根据PriorityOrdered和Ordered筛选,然后调用其postProcessBeanFactory方法
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = postProcessorNames;
        int var22 = postProcessorNames.length;
		
        String ppName;
        for(var9 = 0; var9 < var22; ++var9) {
            ppName = postProcessorNames[var9];
            if (!processedBeans.contains(ppName)) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                } else {
                    currentRegistryProcessors.add(ppName);
                }
            }
        }

        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var23 = orderedPostProcessorNames.iterator();

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

        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var26 = currentRegistryProcessors.iterator();

        while(var26.hasNext()) {
            ppName = (String)var26.next();
            nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

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

代码很长,其实最重要的就是做两件事:

1 对实现了BeanDefinitionRegistry的beanFactory的处理;
2 对普通BeanFactoryPostProcessor的处理;

3.4.2.1 对实现了BeanDefinitionRegistry的beanFactory的处理

这一过程中主要处理的是实现了BeanDefinitionRegistryPostProcessor接口的类,和硬编码的实现了BeanFactoryPostProcessor的类。处理的类型分以下几种情况:

1 硬编码方式注册的BeanDefinitionRegistryPostProcessor处理器;
2 硬编码方法注册的BeanFactoryPostProcessor处理器;
3 通过配置方式注册的BeanDefinitionRegistryPostProcessor处理器;

这里介绍下BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的关系哈。如下:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
3.4.2.2 对普通BeanFactoryPostProcessor的处理

见源码注释。

可以从源码中看到,硬编码方式添加的后置处理器不需要排序,但是通过配置得到的处理器需要排序。spring为了保证排序顺序,用PriorityOrdered和Ordered保证了顺序调用。

3.5 registerBeanPostProcessors(beanFactory):注册BeanPostProcessor处理器

3.5.1 BeanPostProcessor接口的作用介绍

接口源码如下:

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

回顾之前说的bean的加载过程,在bean初始化时,执行了如下代码:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

其中,在

wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);

wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

中就对实现了BeanPostProcessor接口的类重写的postProcessBeforeInitialization和postProcessAfterInitialization方法进行了调用。

3.5.2 registerBeanPostProcessors(beanFactory)源码分析

首先得强调一下,registerBeanPostProcessors只是把BeanPostProcessor注册,而不是激活或者调用。激活是在getBean的时候,上面3.5.1中提到的初始化initializeBean()才是调用它的地方。

源码如下:

    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));
        
		//四种存放BeanPostProcessor的缓存
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();  //这里注意是String类型
        List<String> nonOrderedPostProcessorNames = new ArrayList(); //这里注意是String类型
        
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
        
        //根据PriorityOrdered、Ordered进行筛选
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }
		
		//注册实现了PriorityOrdered接口的BeanPostProcessor
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();
		
		//因为存放实现了Ordered的接口的处理器的缓存为List<String> orderedPostProcessorNames,需要从name--》BeanPostProcessor
        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
		
		//注册实现了Ordered接口的BeanPostProcessor
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();
        
		//因为存放不优先的处理器的缓存为 List<String> nonOrderedPostProcessorNames,需要从name--》BeanPostProcessor
        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        
		//注册未实现PriorityOrdered和Ordered接口的BeanPostProcessor
        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(internalPostProcessors, beanFactory);
        
		//注册实现MergedBeanDefinitionPostProcessor接口的BeanPostProcessor
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

其实看注释的话,这段代码的功能基本就全部了解了。

3.5.3 扩展点

这里有一个疑问:invokeBeanFactoryPostProcessors方法中,对于BeanFactoryPostProcessor,需要从硬编码和配置两方面进行处理,但是registerBeanPostProcessors方法中处理BeanPostProcessor时却没有从硬编码和配置两个方面进行处理,为什么嘞?

答:因为对于BeanFactoryPostProcessor,不止要注册,还要调用,所以需要把所有BeanFactoryPostProcessor找出并调用;而registerBeanPostProcessors只是注册BeanPostProcessor,不需要调用,故不需要硬编码。

在3.5.2的源码中有三处类似如下代码的地方,这里又有一个疑问:假如一个处理器A实现了PriorityOrdered和MergedBeanDefinitionPostProcessor两个接口,那么在如下代码中会在两个缓存中都添加A,最终注册到beanFactory的时候,由于会注入到一个beanPostProcessors中,此时是否会出现重复的A的现象呢?

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

答:不会。spring早都想到这个问题了,哈哈哈。既然担心注册的时候出问题,那么就进入注册BeanPostProcessor的方法registerBeanPostProcessors看看。

(这里的registerBeanPostProcessors是registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors),不是3.5标题上的registerBeanPostProcessors(beanFactory)方法,而是其重载方法)

源码:

	private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        Iterator var2 = postProcessors.iterator();

        while(var2.hasNext()) {
            BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
            beanFactory.addBeanPostProcessor(postProcessor);
        }

    }

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        
      	/*************************   关键点  ***************************
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        **************************/
        
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }

        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }

    }

这样处理的话,遇到重复的会先删再添加,避免重复。

3.6 初始化initApplicationEventMulticaster()

3.6.1 spring监听器的基本使用

自定义如下事件:

public class TestEvent extends ApplicationEvent {
    
    public TestEvent(Object source) {
        super(source);
    }
}

自定义监听器:

public class TestListener implements ApplicationListener<ApplicationEvent> {
    
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof TestEvent){
            System.out.println("bingo");
        }
    }
}

将TestListener 作为一个bean放入容器,并写如下测试类:

	@Test
    public void test2(){
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap12Config.class);
        TestEvent event = new TestEvent("start");
        app.publishEvent(event);
    }

这就完成了一个基本的事件处理。

这个过程运用到了设计模式中的观察者模式。

3.6.2 initApplicationEventMulticaster源码

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的广播器,其可以存放监听器并在需要的时候调用监听器。进入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);
            }
        }

    }

代码逻辑简单来说就是遍历监听器,然后执行监听器。

3.7 registerListeners():注册监听器

和广播器配套使用。感觉不是很重要,略。

3.8 finishBeanFactoryInitialization(beanFactory):非懒加载单例bean的创建

这个可以参考bean加载那一篇。不多赘述。这里讲些别的。

先上源码:

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    	//ConversionService的设置
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        
		//冻结所有bean定义,已有的bean定义无法再做修改
        beanFactory.freezeConfiguration();
		
		//加载剩下的单实例bean
        beanFactory.preInstantiateSingletons();
    }

3.8.1 ConversionService的设置

使用:

//自定义转换器
public class String2DateConverter implements Converter<String, Date> {

    public Date convert(String s) {
        return new Date();
    }
}

//在配置类中增加ConversionServiceFactoryBean类型的bean,并注入String2DateConverter 
@Bean
public ConversionServiceFactoryBean conversionService(){
    ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
    HashSet<Converter> set = new HashSet<Converter>();
    Converter converter = new String2DateConverter();
    set.add(converter);
    conversionServiceFactoryBean.setConverters(set);
    
    return conversionServiceFactoryBean;
}

详细的可以参考以下链接:

【小家Spring】聊聊Spring中的数据转换:Converter、ConversionService、TypeConverter、PropertyEditor

springmvc的 自定义转换器(converter)实现方法

3.8.2 冻结配置

    public void freezeConfiguration() {
        this.configurationFrozen = true;
        this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
    }

3.9 finishRefresh()

    protected void finishRefresh() {
        this.clearResourceCaches();
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

3.9.1initLifecycleProcessor():

当ApplicationContext启动或停止时,会通过LifecycleProcessor来与所有声明的bean的周期做状态更新。而在使用LifecycleProcessor时,需要初始化。以下为源码。

    protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("lifecycleProcessor")) {
            this.lifecycleProcessor = (LifecycleProcessor)beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
            }
        } else {
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton("lifecycleProcessor", this.lifecycleProcessor);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [" + this.lifecycleProcessor + "]");
            }
        }

    }

可以看出,这里和初始化广播器时很像,如果用户自定义,则使用用户自定义的;否则用spring默认的。

3.9.2 this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));

当完成ApplicationContext的初始化时,要通过spring中的事件发布机制发出ContextRefreshedEvent事件,从而使得监听器做进一步处理。

源码如下:

    protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Publishing event in " + this.getDisplayName() + ": " + event);
        }

        Object applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent)event;
        } else {
            applicationEvent = new PayloadApplicationEvent(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
            }
        }

        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        } else {
            this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
        }

        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
            } else {
                this.parent.publishEvent(event);
            }
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值