区分environment,applicationContext,BeanFactory
applicationContext:
spring应用上下文,类中持有environment和BeanFactory接口等实现类的引用,也可以理解为在applicationContext皮衣下包装了各种顶级接口实现类。
environment:
spring应用的运行环境,保存了当前操作系统,JVM,被激活的application.properties文件的配置信息。
BeanFactory:
狭义讲,保存了所有业务类的字节码和对象,广义讲,保存了BeanDefinition和Bean对象。
environment内部结构
environment对象更像是一个各种配置信息的一个持有者,外部可以通过该对象获取到各种配置的信息,里面主要包括这几个内部引用:
PropertySource:
类似Map,但没有put功能,只能从里面get数据,代表每个配置文件的一组配置属性,在environment中是以MutablePropertySources而存在,在该类中持有List(PropertySource)对象。
PropertyResolver:
顾名思义,就是做配置信息解析的,该接口提供了一个getProperty()方法,从List(PropertySource)取出相应数据,这里包括负责解析${xxx}包起来的属性。environment也继承了该接口,所以也具备了该功能。
维护环境信息:
environment内部还维护着被激活环境(dev,pro,test)的信息,被激活的环境信息是保存在activeProfiles(Set(String))字段中。
从refresh()方法说起
对于应用上的配置信息都是保存在PropertySource当中,不同的类型的配置信息保存在不同的PropertySource中,所以已知的有三个PropertySource对象,一个JVM配置信息,一个系统配置信息,一个properties文件配置信息。
加载系统配置信息和JVM配置信息
1.refresh()调用prepareRefresh()方法
2.prepareRefresh()调用initPropertySources()方法
3.initPropertySources()调用getEnvironment()方法
4.getEnvironment()创建了StandardEnvironment对象
5.StandardEnvironment对象有这个方法customizePropertySources(),该方法就创建了两个PropertySource,分别对应上系统和JVM的配置信息。
6.customizePropertySources()方法调用时机:StandardEnvironment对象被创建时,其父类AbstractEnvironment构造方法会调用该方法。
7.再看回customizePropertySources()方法中的两个关键方法,一个是获取JVM的配置信息,一个是获取系统的配置信息,里面的两个方法最终都是从System类中取得数据,System类是JDK提供的类,这里不扩展。
加载application.properties文件配置信息
application.properties配置文件的信息最终也会以PropertySource保存到spring应用当中,那如何解析到该配置文件呢?得从一个关键类说起,这个类PropertySourcesPlaceholderConfigurer负责解析该配置文件,并转成前文所提的PropertySonrce并存入environment中,该类实现了BeanFactoryPostProcessor这个扩展接口,在启动spring启动的时候会调用该类的核心方法postProcessBeanFactory()。
1.refresh()调用invokeBeanFactoryPostProcessors()方法
2.invokeBeanFactoryPostProcessors()调用invokeBeanFactoryPostProcessors()
3.invokeBeanFactoryPostProcessors()调用invokeBeanFactoryPostProcessors()
4.invokeBeanFactoryPostProcessors()调用所有实现BeanFactoryPostProcessor接口的postProcessBeanFactory()方法,当然也包括PropertySourcesPlaceholderConfigurer该类的方法。
今天关于environment就介绍到这里了,感激观看!!!