容器的性能扩大和refresh办法解析

在之前文章中咱们理解了对于Spring中bean的加载流程,并始终应用BeanFactory接口以及它的默认实现类XmlBeanFactory,在Spring中还提供了另一个接口ApplicationContext,用于扩大BeanFactory中现有的性能。

首先BeanFactory和ApplicationContext都是用于加载bean的,然而相比之下,ApplicationContext提供了更多的扩大性能,ApplicationContext蕴含了BeanFactory的所有性能。通常咱们会优先应用ApplicationContext。

咱们来看看ApplicationContext多了哪些性能?

首先看一下写法上的不同。

应用BeanFactory形式加载XML

final BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

应用ApplicationContext形式加载XML

final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");

咱们开始点开ClassPathXmlApplicationContext的构造函数,进行剖析。

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {   this(new String[] {configLocation}, true, null);}
public ClassPathXmlApplicationContext(      String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)      throws BeansException {   super(parent);   setConfigLocations(configLocations);   if (refresh) {      refresh();   }}

在ClassPathXmlApplicationContext中能够将配置文件门路以数组的模式传入,对解析及性能实现都在refresh()办法中实现。

设置配置门路

public void setConfigLocations(@Nullable String... locations) {   if (locations != null) {      Assert.noNullElements(locations, "Config locations must not be null");      this.configLocations = new String[locations.length];      for (int i = 0; i < locations.length; i++) {         this.configLocations[i] = resolvePath(locations[i]).trim();      }   }   else {      this.configLocations = null;   }}

此函数次要解析给定的门路数组,如果数组中蕴含特殊符号,如${var},那么在resolvePath办法中会搜查匹配的零碎变量并替换。

扩大性能

设置完门路后,就能够对文件进行解析和各种性能的实现,能够说在refresh办法中简直蕴含了ApplicationContext中提供的全副性能,而且此函数的逻辑也非常清晰,能够很容易剖析对应档次和逻辑。

public void refresh() throws BeansException, IllegalStateException {   synchronized (this.startupShutdownMonitor) {      // 筹备刷新的上下文环境,包含设置启动工夫,是否激活标识位      // 初始化属性源(property source)配置      prepareRefresh();      // 初始化BeanFactory 并进行xml文件读取      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();      // 对BeanFactory进行各种性能填充      prepareBeanFactory(beanFactory);      try {         // 子类笼罩办法做额定的解决         postProcessBeanFactory(beanFactory);         // 激活各种BeanFactory处理器         invokeBeanFactoryPostProcessors(beanFactory);         // 注册拦挡bean创立的bean处理器,只是注册,具体调用在getBean中         registerBeanPostProcessors(beanFactory);         // 为上下文初始化Message源,国际化解决         initMessageSource();         // 初始化利用音讯播送器,并放入applicationEventMulticaster bean中         initApplicationEventMulticaster();         // 留给子类来初始化其余的bean         onRefresh();         // 在所有注册的bean中查找Listener bean,注册到音讯播送器中         registerListeners();         // 初始化剩下的单例bean (非惰性)         finishBeanFactoryInitialization(beanFactory);         //实现刷新过程,告诉生命周期处理器LifecycleProcessor刷新过程,同时收回ContextRefreshEvent告诉他人         finishRefresh();      }      catch (BeansException ex) {         if (logger.isWarnEnabled()) {            logger.warn("Exception encountered during context initialization - " +                  "cancelling refresh attempt: " + ex);         }         // 销毁曾经初始化的 singleton 的 Beans,免得有些 bean 会始终占用资源         destroyBeans();         // 重置流动标记         cancelRefresh(ex);         throw ex;      }      finally {         //重置公共缓存         resetCommonCaches();      }   }}

咱们总结一下初始化的步骤。

  1. 初始化前的筹备工作,例如对系统属性或者环境变量进行筹备及验证
  2. 初始化BeanFactory,并对XML文件进行读取。之前咱们说过ClassPathXmlApplicationContext中蕴含着BeanFactory所提供的所有特色,那么在这一步将会复用BeanFactory中的配置文件读取解析及其他性能,在这一步之后ClassPathXmlApplicationContext就曾经蕴含了BeanFactory所提供的性能,也就是能够对bean进行提取等操作
  3. 对BeanFactory进行各种性能填充
  4. 子类笼罩办法做额定的解决。次要用于咱们在业务上做进一步扩大
  5. 激活各种BeanFactory处理器
  6. 注册拦挡bean创立的bena处理器,这里仅仅是注册,真正调用在getBean中
  7. 为上下文初始化Message源,对不同语言的音讯体进行国际化解决
  8. 初始化利用音讯播送器,并放入"applicationEventMulticaster" bean中
  9. 留给子类来初始化其余的bean
  10. 在所有注册的bean中查找listener bean,注册到音讯播送器中
  11. 初始化剩下的单实例(非惰性)
  12. 实现刷新过程,告诉生命周期处理器lifecycleProcessor刷新过程,同时收回ContextRefreshEvent来告诉他人

环境筹备

prepareRefresh办法次要做些筹备工作,比方对系统属性及环境变量的初始化及验证。

  1. initPropertySources

该办法外面是一个空实现,次要用于给咱们依据须要去重写该办法,并在办法中进行个性化的属性解决及设置。

protected void initPropertySources() {        // For subclasses: do nothing by default.}
  1. validateRequiredProperties 该办法次要对属性进行验证。默认状况下什么也没校验。在咱们继承了ClassPathXmlApplicationContext类重写了initPropertySources办法后会进行相干校验。

加载BeanFactory

obtainFreshBeanFactory 办法次要用来获取BeanFactory,方才说过ApplicationContext领有BeanFactory的所有性能,这个办法就是实现BeanFactory的中央,也就是说调用完该办法后,applicationContext就领有了BeanFactory的性能。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {   //初始化BeanFactory,并进行XML文件读取,将失去的BeanFactory记录到以后实体属性中   refreshBeanFactory();   //返回以后实体的beanFactory属性   return getBeanFactory();}
protected final void refreshBeanFactory() throws BeansException {   if (hasBeanFactory()) {      destroyBeans();      closeBeanFactory();   }   try {      DefaultListableBeanFactory beanFactory = createBeanFactory();      beanFactory.setSerializationId(getId());      customizeBeanFactory(beanFactory);      loadBeanDefinitions(beanFactory);      synchronized (this.beanFactoryMonitor) {         this.beanFactory = beanFactory;      }   }   catch (IOException ex) {      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);   }}

咱们进入AbstractRefreshableApplicationContext#refreshBeanFactory()办法中。

protected final void refreshBeanFactory() throws BeansException {        //判断是否存在beanFactory        if (hasBeanFactory()) {            //销毁所有单例            destroyBeans();            //重置beanFactory            closeBeanFactory();        }        try {            //创立beanFactory            DefaultListableBeanFactory beanFactory = createBeanFactory();            //设置序列化id            beanFactory.setSerializationId(getId());            //定制beanFactory,设置相干属性,包含是否容许笼罩同名称不同定义的对象以及循环依赖            customizeBeanFactory(beanFactory);            //初始化DocumentReader,进行XML读取和解析            loadBeanDefinitions(beanFactory);            synchronized (this.beanFactoryMonitor) {                this.beanFactory = beanFactory;            }        }        catch (IOException ex) {            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);        }}

总结一下这个办法的流程:

  1. 创立DefaultListableBeanFactory。申明形式为:BeanFactory bf = new XmlBeanFactory("beanFactoryTest.xml"),其中的XmlBeanFactory继承自DefaultListableBeanFactory,并提供了XmlBeanDefinitionReader类型的reader属性,也就是说DefaultListableBeanFactory是容器的根底,必须首先实例化,这里就是实例化DefaultListableBeanFactory的步骤
  2. 指定序列化ID
  3. 定制BeanFactory
  4. 加载BeanDefinition
  5. 应用全局变量记录BeanFactory类实例

定制BeanFactory

首先咱们先理解customizeBeanFactory办法,该办法是在根本容器的根底上,减少了是否容许笼罩、是否容许扩大的设置。

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {   //如果不为空,设置beanFactory对象响应的属性,含意:是否容许笼罩同名称的不同定义的对象   if (this.allowBeanDefinitionOverriding != null) {      beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);   }   //如果属性不为空,设置给beanFactory对象相应属性,含意:是否容许bean之间存在循环依赖   if (this.allowCircularReferences != null) {      beanFactory.setAllowCircularReferences(this.allowCircularReferences);   }}

具体这里只是做了简略的判断,具体设置属性的中央,应用子类笼罩即可。例如:

/** * @author 神秘杰克 * 公众号: Java菜鸟程序员 * @date 2022/6/12 * @Description 自定义ClassPathXmlApplicationContext */public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {   @Override   protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {      super.setAllowBeanDefinitionOverriding(false);      super.setAllowCircularReferences(false);      super.customizeBeanFactory(beanFactory);   }}

加载BeanDefinition

在初始化了DefaultListableBeanFactory后,咱们还须要XmlBeanDefinitionReader来读取XML文件,这个步骤中首先要做的就是初始化XmlBeanDefinitionReader。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {   //为指定beanFactory创立XmlBeanDefinitionReader   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);   //进行环境变量的设置   beanDefinitionReader.setEnvironment(this.getEnvironment());   beanDefinitionReader.setResourceLoader(this);   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));   //对beanDefinitionReader进行设置,能够笼罩   initBeanDefinitionReader(beanDefinitionReader);   loadBeanDefinitions(beanDefinitionReader);}

初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader后,咱们就能够进行配置文件的读取了。最终XmlBeanDefinitionReader所去读的BeanDefinitionHolder都会注册到DefaultListableBeanFactory中。

通过该办法后类型为DefaultListableBeanFactory中的变量beanFactory曾经蕴含了所有解析好的配置。对于配置文件的读取这一部分之前文章曾经讲过,这里就不再赘述。

性能扩大

咱们在实现了配置文件解析后,咱们接着进入prepareBeanFactory办法。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {   //设置beanFactory的ClassLoader为以后context的ClassLoader   beanFactory.setBeanClassLoader(getClassLoader());   //设置beanFactory的表达式语言解决   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));   //为beanFactory减少了一个默认的propertyEditor,次要是对bean的属性等设置治理的一个工具   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(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);   //减少了ApplicationListenerDetector次要是检测bean是否实现了ApplicationListener接口   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));   //减少对AspectJ的反对   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));      // Set a temporary ClassLoader for type matching.      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));   }   //增加默认的零碎环境bean   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());   }   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());   }   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());   }}

该办法次要做了几个方面的扩大:

  • 减少了对SpEL语言的反对
  • 减少了对属性编辑器的反对
  • 减少了一些内置类,比方EnvironmentAware、MessageSourceAware的信息注入
  • 设置了依赖性能可疏忽的接口
  • 注册了一些固定依赖的属性
  • 减少AspectJ的反对
  • 将相干环境变量及属性注册以单例模式注册

BeanFactory的后处理

BeanFactory作为Spring中容器的根底,用于寄存所有曾经加载的bean,为了保障程序的高扩展性,Spring针对BeanFactory做了大量的扩大,比方PostProcessor等都是在这里实现的。

激活注册的BeanFactoryPostProcessor

在学习之前,咱们先理解一下BeanFactoryPostProcessor的用法。BeanFactoryPostProcessor接口和BeanPostProcessor相似,能够对bean的定义进行解决。也就是说,Spring IOC容器容许BeanFactoryPostProcessor在容器实例化任何bean之前读取配置元数据,并能够批改它。BeanFactoryPostProcessor能够配置多个,通过实现Ordered接口设置“order”来管制执行程序。

须要留神的是如果在容器中定义一个BeanFactoryPostProcessor,它仅仅对此容器中的bean进行后置解决。BeanFactoryPostProcessor不会对其余容器中的bean进行后置解决。

1.BeanFactoryPostProcessor的典型利用:PropertySourcesPlaceholderConfigurer

首先咱们来看一下配置文件:

<bean id="hello" class="cn.jack.Hello">   <property name="msg">      <value>${bean.msg}</value>   </property></bean>

在外面咱们应用到了变量援用:${bean.msg},这就是Spring的扩散配置,咱们能够在配置文件中配置该属性的值。

application.properties

bean.msg=hi

而后咱们再进行配置文件的配置。

<bean id="helloHandler" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">        <property name="locations">            <list>                <value>application.properties</value>            </list>        </property>    </bean>

这时候就明确了,咱们通过PreferencesPlaceholderConfigurer中进行获取咱们的配置信息。咱们查看该类能够晓得间接性继承了BeanFactoryPostProcessor接口。

当Spring加载任何实现了这个接口的bean时,都会在bean工厂加载所有bena的配置之后执行postProcessBeanFactory办法。在办法中先后调用了mergeProperties、convertProperties、processProperties这三个办法,别离失去配置、将失去的配置进行转换为适合的类型、最初将配置内容告知BeanFactory。

正是通过实现BeanFactoryPostProcessor,BeanFactory会在实例化任何bean之前取得配置信息,从而可能正确解析bean配置文件中的变量援用

PropertySourcesPlaceholderConfigurer曾经取代了PropertyPlaceholderConfigurer,因为汇聚了Environment、多个PropertySource。所以它可能管制取值优先级、程序,并且还提供了拜访的办法,前期再想获取也不是问题。

2.应用自定义BeanFactoryPostProcessor

咱们本人实现一个自定义BeanFactoryPostProcessor,去除咱们不想要显示的属性值的性能来展现自定义BeanFactoryPostProcessor的创立及应用,例如bean定义中咱们屏蔽掉‘guapi’、‘shazi’。

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean class="cn.jack.ObscenityRemovingBeanFactoryPostProcessor" id="customBeanFactoryPostProcessor">        <property name="obscenities">            <set>                <value>guapi</value>                <value>shazi</value>            </set>        </property>    </bean>    <bean class="cn.jack.SimpleBean" id="simpleBean">        <property name="userName" value="jack"/>        <property name="address" value="guapi"/>        <property name="email" value="shazi"/>    </bean></beans>
public class SimpleBean {   private String userName;   private String email;   private String address;        //getter  setter}
public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {   private final Set<String> obscenities;   public ObscenityRemovingBeanFactoryPostProcessor() {      this.obscenities = new HashSet<>();   }   /**    * 将所有bean 的参数中含有 obscenities 汇合中的值进行屏蔽    */   @Override   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {      String[] beanNames = beanFactory.getBeanDefinitionNames();      for (String beanName : beanNames) {         final BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);         StringValueResolver valueResolver = strVal -> {            if (isObscene(strVal)){               return  "*****";            }            return strVal;         };         final BeanDefinitionVisitor beanDefinitionVisitor = new BeanDefinitionVisitor(valueResolver);         beanDefinitionVisitor.visitBeanDefinition(beanDefinition);      }   }   public boolean isObscene(Object value){      String potentialObscenity = value.toString().toUpperCase();      return this.obscenities.contains(potentialObscenity);   }   public void setObscenities(Set<String> obscenities){      this.obscenities.clear();      for (String obscenity : obscenities) {         this.obscenities.add(obscenity.toUpperCase());      }   }}

启动类:

public class Test {   public static void main(String[] args) {      ApplicationContext ac = new ClassPathXmlApplicationContext("beanFactory.xml");      SimpleBean simpleBean = (SimpleBean) ac.getBean("simpleBean");      System.out.println(simpleBean);   }}

输入后果:

SimpleBean{userName='jack', email='*****', address='*****'}

咱们通过ObscenityRemovingBeanFactoryPostProcessor咱们很好的屏蔽掉了咱们不想要显示的属性。

激活BeanFactoryPostProcessor

咱们在理解了BeanFactoryPostProcessor的用法之后就能够持续回到咱们的refresh办法中持续钻研源码了。

进入invokeBeanFactoryPostProcessors办法中。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));   }}

咱们持续进入具体重载办法中invokeBeanFactoryPostProcessors。

public static void invokeBeanFactoryPostProcessors(      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {   // 将曾经执行过的BeanFactoryPostProcessor存储在processedBeans,避免反复执行   Set<String> processedBeans = new HashSet<>();   //对BeanDefinitionRegistry类型进行解决   if (beanFactory instanceof BeanDefinitionRegistry) {      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;      // 用来寄存BeanFactoryPostProcessor对象      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();      // 用来寄存BeanDefinitionRegistryPostProcessor对象      // 不便对立执行实现了BeanDefinitionRegistryPostProcessor接口父类的办法      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();      // 解决内部定义的BeanFactoryPostProcessor,将BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor辨别开      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {            BeanDefinitionRegistryPostProcessor registryProcessor =                  (BeanDefinitionRegistryPostProcessor) postProcessor;            //对于BeanDefinitionRegistryPostProcessor类型,须要先调用此办法,再增加到汇合中            registryProcessor.postProcessBeanDefinitionRegistry(registry);            registryProcessors.add(registryProcessor);         } else {            //记录惯例BeanFactoryPostProcessor            regularPostProcessors.add(postProcessor);         }      }      //寄存以后须要执行的BeanDefinitionRegistryPostProcessor      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();      // 调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor。      // 获取所有实现了BeanDefinitionRegistryPostProcessor接口的类名      String[] postProcessorNames =            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);      for (String ppName : postProcessorNames) {         //判断以后类是否实现了PriorityOrdered接口         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {            //将BeanDefinitionRegistryPostProcessor类型存入currentRegistryProcessors中            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));            // 提前寄存到processedBeans,防止反复执行,然而此处还未执行            processedBeans.add(ppName);         }      }      //对currentRegistryProcessors汇合中的BeanDefinitionRegistryPostProcessor类型进行排序      sortPostProcessors(currentRegistryProcessors, beanFactory);      // 增加到registryProcessors汇合,用于后续执行父接口的postProcessBeanFactory办法      registryProcessors.addAll(currentRegistryProcessors);      // 遍历汇合,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()办法      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);      //执行结束后清空该汇合      currentRegistryProcessors.clear();      // 接着,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors      // 这里再次获取BeanDefinitionRegistryPostProcessor,是因为有可能在下面办法执行过程中增加了BeanDefinitionRegistryPostProcessor      // 而上面解决BeanFactoryPostProcessor的时候又不须要反复获取了是为什么呢?      // 因为增加BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor中增加,在BeanFactoryPostProcessor是无奈增加的      for (String ppName : postProcessorNames) {         // 判断以后bean没有被执行过,并且实现了Ordered接口         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {            //如果BeanFactory中没有该Bean则会去创立该Bean            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));            processedBeans.add(ppName);         }      }      sortPostProcessors(currentRegistryProcessors, beanFactory);      registryProcessors.addAll(currentRegistryProcessors);      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);      currentRegistryProcessors.clear();      //最初解决没有实现Ordered与PriorityOrdered接口的BeanDefinitionRegistryPostProcessor      boolean reiterate = true;      while (reiterate) {         reiterate = false;         // 再次获取BeanDefinitionRegistryPostProcessor         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);         for (String ppName : postProcessorNames) {            if (!processedBeans.contains(ppName)) {               // 将本次要执行的BeanDefinitionRegistryPostProcessor寄存到currentRegistryProcessors               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));               processedBeans.add(ppName);               reiterate = true;            }         }         sortPostProcessors(currentRegistryProcessors, beanFactory);         registryProcessors.addAll(currentRegistryProcessors);         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);         currentRegistryProcessors.clear();      }      //当初,调用到目前为止解决的所有处理器的 postProcessBeanFactory 回调。      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);   } else {      // BeanFactory如果不归属于BeanDefinitionRegistry类型,则间接执行beanFactoryPostProcessor      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);   }   String[] postProcessorNames =         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);   // 用于寄存实现了priorityOrdered接口的BeanFactoryPostProcessor   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();   // 用于寄存实现了ordered接口的BeanFactoryPostProcessor名称   List<String> orderedPostProcessorNames = new ArrayList<>();   // 用于寄存无排序的BeanFactoryPostProcessor名称   List<String> nonOrderedPostProcessorNames = new ArrayList<>();   for (String ppName : postProcessorNames) {      // 如果曾经执行过了,则不做解决      if (processedBeans.contains(ppName)) {         // skip - already processed in first phase above      }      // 如果实现了PriorityOrdered 则增加      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));      }      // 如果实现了Ordered 则增加      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {         orderedPostProcessorNames.add(ppName);      }      //如果没有排序则增加到指定汇合      else {         nonOrderedPostProcessorNames.add(ppName);      }   }   // 首先调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);   // 而后调用实现 Ordered 的 BeanFactoryPostProcessors。   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());   for (String postProcessorName : orderedPostProcessorNames) {      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));   }   sortPostProcessors(orderedPostProcessors, beanFactory);   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);   // 最初调用其余没有排序的 BeanFactoryPostProcessor。   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());   for (String postProcessorName : nonOrderedPostProcessorNames) {      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));   }   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);   // 清空缓存   beanFactory.clearMetadataCache();}

注册BeanPostProcessor

理解了BeanFactoryPostProcessors的调用后,咱们当初来理解下BeanPostProcessor,这里仅仅是注册,并不是调用。真正的调用在bean实例化阶段进行的。

在BeanFactory中并没有实现后处理器的主动注册性能,所以在调用的时候如果没有进行被动注册则是不可能应用的。然而在ApplicationContext中增加了被动注册性能。

比方自定义这样的后处理器:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {   @Override   public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {      System.out.println("===");      return null;   }}
<bean class="cn.jack.MyInstantiationAwareBeanPostProcessor"/>

在应用ApplicationContext形式获取bean的时候会在获取之前打印出“===”,在BeanFactory形式进行bean的加载是不会有该打印的。

这个个性就是在registerBeanPostProcessors中实现的。

public static void registerBeanPostProcessors(      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {   //获取所有实现BeanPostProcessor接口的类   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);   //注册一个 BeanPostProcessorChecker,用来记录 bean 在 BeanPostProcessor 实例化时的信息   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));   //辨别实现不同接口的 BeanPostProcessors   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();   List<String> orderedPostProcessorNames = new ArrayList<>();   List<String> nonOrderedPostProcessorNames = new ArrayList<>();   //依据不同类型进行add   for (String ppName : postProcessorNames) {      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {         BeanPostProcessor pp = 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 的 BeanPostProcessors   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);   //注册实现Ordered接口的BeanPostProcessors   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());   for (String ppName : orderedPostProcessorNames) {      //拿到ppName对应的BeanPostProcessor实例对象      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);      //将ppName对应的BeanPostProcessor实例对象增加到orderedPostProcessors, 筹备执行注册      orderedPostProcessors.add(pp);      if (pp instanceof MergedBeanDefinitionPostProcessor) {         //如果ppName对应的bean实例也实现了MergedBeanDefinitionPostProcessor接口,则增加到该汇合中         internalPostProcessors.add(pp);      }   }   //对orderedPostProcessors进行排序并注册   sortPostProcessors(orderedPostProcessors, beanFactory);   registerBeanPostProcessors(beanFactory, orderedPostProcessors);   //注册所有惯例的BeanPostProcessors,过程同上   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());   for (String ppName : nonOrderedPostProcessorNames) {      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);      nonOrderedPostProcessors.add(pp);      if (pp instanceof MergedBeanDefinitionPostProcessor) {         internalPostProcessors.add(pp);      }   }   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);   //注册所有mergedBeanDefinitionPostProcessor类型的BeanPostProcessor,并非反复注册   //在beanFactory.addBeanPostProcessor中会先移除曾经存在的BeanPostProcessor   sortPostProcessors(internalPostProcessors, beanFactory);   registerBeanPostProcessors(beanFactory, internalPostProcessors);   // 增加ApplicationListener探测器   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

初始化音讯资源

在initMessageSource中次要性能是提取配置文件中的messageSource,并将其记录在Spring容器中,也就是ApplicationContext中。如果用户未设置资源文件的话,则获取Spring默认的配置delegatingMessageSource。

protected void initMessageSource() {   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   // Bean 的名称必须要是 messageSource   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { //MESSAGE_SOURCE_BEAN_NAME = messageSource      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);      // Make MessageSource aware of parent MessageSource.      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;         if (hms.getParentMessageSource() == null) {            // Only set parent context as parent MessageSource if no parent MessageSource            // registered already.            hms.setParentMessageSource(getInternalParentMessageSource());         }      }      if (logger.isTraceEnabled()) {         logger.trace("Using MessageSource [" + this.messageSource + "]");      }   }   else {      //如果用户并没有定义配置文件,那么应用长期的DelegatingMessageSource以便于作为调用getMessage的返回      DelegatingMessageSource dms = new DelegatingMessageSource();      dms.setParentMessageSource(getInternalParentMessageSource());      this.messageSource = dms;      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);      if (logger.isTraceEnabled()) {         logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");      }   }}

这里规定资源文件必须为messageSource,否则就会获取不到自定义资源配置。

初始化ApplicationEventMulticaster

initApplicationEventMulticaster办法实现比较简单,存在两种状况:

  • 如果用户自定义了事件播送器,那么就是用用户自定义的事件播送器
  • 如果用户没有自定义事件播送器,那么应用默认的ApplicationEventMulticaster
protected void initApplicationEventMulticaster() {   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   //判断容器中是否存在BeanDefinitionName为applicationEventMulticaster的bd,也就是自定义的事件监听多路播送器,必须实现ApplicationEventMulticaster接口   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {      this.applicationEventMulticaster =            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);      if (logger.isTraceEnabled()) {         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");      }   }   else {      //如果没有,则默认采纳SimpleApplicationEventMulticaster      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);      if (logger.isTraceEnabled()) {         logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +               "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");      }   }}

最初,作为播送器,肯定是用于寄存监听器并在适合的时候调用监听器,咱们进入默认的播送器实现类SimpleApplicationEventMulticaster中看一下。

看到如下办法:

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));   Executor executor = getTaskExecutor();   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {      if (executor != null) {         executor.execute(() -> invokeListener(listener, event));      }      else {         invokeListener(listener, event);      }   }}

能够推断,当产生Spring事件的时候会默认应用SimpleApplicationEventMulticaster的multicastEvent来播送事件,遍历所有监听器,并应用监听器中的onApplicationEvent办法来进行监听器的解决。而对于每个监听器来说其实都能够获取到产生的事件,然而是否进行解决则由事件监听器决定。

注册监听器

咱们重复提到了监听器,咱们接下来看一下Spring注册监听器的时候又做了哪些逻辑操作?

protected void registerListeners() {   // 首先注册动态的指定的监听器,注册的是非凡的事件监听器,而不是配置中的bean   for (ApplicationListener<?> listener : getApplicationListeners()) {      getApplicationEventMulticaster().addApplicationListener(listener);   }   // 这里不会初始化FactoryBean,咱们须要保留所有的一般bean   // 不会实例化这些bean,让后置处理器能够感知到它们   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);   for (String listenerBeanName : listenerBeanNames) {      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);   }   // 当初有了事件播送组,公布之前的利用事件   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;   this.earlyApplicationEvents = null;   if (earlyEventsToProcess != null) {      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {         getApplicationEventMulticaster().multicastEvent(earlyEvent);      }   }}

只是将一些非凡的监听器注册到播送组中,那些在bean配置文件中实现了ApplicationListener接口的类还没有实例化,所以此时只是将name保留到了播送组中,将这些监听器注册到播送组中的操作时在bean的后置处理器中实现的,那时候bean的实例化曾经实现了。

初始化非提早加载单例

实现BeanFactory的初始化工作,其中包含ConversionService的设置、配置解冻以及非提早加载的bean的初始化工作。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {   // 初始化此上下文的转换服务   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {      beanFactory.setConversionService(            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));   }   // 如果beanFactory之前没有注册解析器,则注册默认的解析器,例如${}解析成真正的属性:次要用于注解属性值的解析   if (!beanFactory.hasEmbeddedValueResolver()) {      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));   }   //解决 @EnableLoadTimeWeaving 或  <context:load-time-weaver/> 标记的类   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);   for (String weaverAwareName : weaverAwareNames) {      getBean(weaverAwareName);   }   //长期类加载器设置为空   beanFactory.setTempClassLoader(null);   //解冻所有的bean定义,阐明注册的bean定义将不被批改或者进一步解决   beanFactory.freezeConfiguration();   //初始化剩下的单例实例(非惰性)   beanFactory.preInstantiateSingletons();}

首先,咱们先理解下ConversionService类所提供的作用。

1.ConversionService的设置

之前咱们提到能够用自定义类型转换器把String类型转换为Date,在Spring中也提供了应用Converter来进行转换。

2.解冻配置

解冻所有的bean定义,阐明注册的bean定义将不被批改或者进行任何一步的解决。

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

3.初始化提早加载

ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化也就意味着作为初始化过程的一部分,ApplicationContext实例会创立并配置所有单例bean,这个实例化过程就是在finishBeanFactoryInitialization办法中的preInstantiateSingletons办法中实现的。

public void preInstantiateSingletons() throws BeansException {   if (logger.isTraceEnabled()) {      logger.trace("Pre-instantiating singletons in " + this);   }   //创立beanDefinitionNames的正本beanNames用于后续的遍历,以容许init等办法注册新的bean定义   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);   //遍历beanNames,触发所有非懒加载单例bean的初始化   for (String beanName : beanNames) {      //获取beanName对应的MergedBeanDefinition      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);      //bd对应的不是抽象类 && 并且是单例 && 并且不是懒加载      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {         //判断是否为FactoryBean         if (isFactoryBean(beanName)) {            //通过前缀&和beanName拿到Bean            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);            //如果为FactoryBean            if (bean instanceof FactoryBean) {               final FactoryBean<?> factory = (FactoryBean<?>) bean;               //判断这个FactoryBean是否心愿急迫的初始化               boolean isEagerInit;               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)                              ((SmartFactoryBean<?>) factory)::isEagerInit,                        getAccessControlContext());               }               else {                  isEagerInit = (factory instanceof SmartFactoryBean &&                        ((SmartFactoryBean<?>) factory).isEagerInit());               }               //如果心愿急迫的初始化,则通过beanName获取bean实例               if (isEagerInit) {                  getBean(beanName);               }            }         }         else {            //如果beanName对应的bean不是FactoryBean,只是一般Bean,通过beanName获取bean实例            getBean(beanName);         }      }   }   //遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调   for (String beanName : beanNames) {      //拿到beanName对应的bean实例      Object singletonInstance = getSingleton(beanName);      //判断singletonInstance是否实现了SmartInitializingSingleton接口      if (singletonInstance instanceof SmartInitializingSingleton) {         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;         //触发SmartInitializingSingleton实现类的afterSingletonsInstantiated办法         if (System.getSecurityManager() != null) {            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {               smartSingleton.afterSingletonsInstantiated();               return null;            }, getAccessControlContext());         }         else {            smartSingleton.afterSingletonsInstantiated();         }      }   }}

finishRefresh

在Spring中提供了Lifecycle接口,该接口蕴含start/stop办法,实现此接口后Spring会保障在启动时候调用其start办法开始申明周期,并在Spring敞开时候调用stop办法来完结申明周期。通常用来配置后台程序,在启动后始终运行(比方MQ)而ApplicationContext最初一步finishRefresh办法就是实现这一性能。

protected void finishRefresh() {   //革除资源缓存   clearResourceCaches();   //1.为此上下文初始化生命周期处理器   initLifecycleProcessor();   //2.首先将刷新结束事件流传到生命周期处理器(触发isAutoStartup办法返回true的SmartLifecycle的start办法)   getLifecycleProcessor().onRefresh();   //3.推送上下文刷新结束事件到相应的监听器   publishEvent(new ContextRefreshedEvent(this));   // Participate in LiveBeansView MBean, if active.   LiveBeansView.registerApplicationContext(this);}

1.initLifecycleProcessor

当ApplicationContext启动或进行时,它会通过LifecycleProcessor来和所有申明的bean的周期做状态更新,而在LifecycleProcessor的应用前首先进行初始化。

protected void initLifecycleProcessor() {   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   //判断BeanFactory是否曾经存在生命周期处理器(beanName=lifecycleProcessor)   if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {      this.lifecycleProcessor =            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);      if (logger.isTraceEnabled()) {         logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");      }   }   else {      //如果不存在,则应用DefaultLifecycleProcessor      DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();      defaultProcessor.setBeanFactory(beanFactory);      this.lifecycleProcessor = defaultProcessor;      // 并将DefaultLifecycleProcessor作为默认的生命周期处理器,注册到BeanFactory中      beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);      if (logger.isTraceEnabled()) {         logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +               "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");      }   }}

2.onRefresh

启动所有实现了Lifecycle接口的bean

public void onRefresh() {   startBeans(true);   this.running = true;}
private void startBeans(boolean autoStartupOnly) {   Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();   Map<Integer, LifecycleGroup> phases = new HashMap<>();   lifecycleBeans.forEach((beanName, bean) -> {      if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {         int phase = getPhase(bean);         LifecycleGroup group = phases.get(phase);         if (group == null) {            group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);            phases.put(phase, group);         }         group.add(beanName, bean);      }   });   if (!phases.isEmpty()) {      List<Integer> keys = new ArrayList<>(phases.keySet());      Collections.sort(keys);      for (Integer key : keys) {         phases.get(key).start();      }   }}

3.publishEvent

当实现ApplicationContext初始化的时候,要通过Spring中的公布机制来收回ContextRefreshedEvent事件,以保障对应的监听器能够做进一步的逻辑解决。

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {   Assert.notNull(event, "Event must not be null");   //如有必要,将事件装璜为ApplicationEvent   ApplicationEvent applicationEvent;   if (event instanceof ApplicationEvent) {      applicationEvent = (ApplicationEvent) event;   }   else {      applicationEvent = new PayloadApplicationEvent<>(this, event);      if (eventType == null) {         eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();      }   }   // Multicast right now if possible - or lazily once the multicaster is initialized   if (this.earlyApplicationEvents != null) {      this.earlyApplicationEvents.add(applicationEvent);   }   else {      //应用事件播送器播送事件到相应的监听器      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);   }   //通过parent公布事件   if (this.parent != null) {      if (this.parent instanceof AbstractApplicationContext) {         ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);      }      else {         this.parent.publishEvent(event);      }   }}

到这里,refresh办法就解析实现了。下一步就是AOP了。