Spring容器功能扩展的方法

本篇内容介绍了“Spring容器功能扩展的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

公司主营业务:网站制作、成都网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联推出乡宁免费做网站回馈大家。

1、ApplicationContext

ApplicationContext ctx = new ClassPathXmlApplicationContext("beanFactory.xml");

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

   super(parent);
   setConfigLocations(configLocations);
   if (refresh) {
      refresh();
   }
}
public void setConfigLocations(String[] locations) {
   if (locations != 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;
   }
}

2、扩展功能

if (refresh) {
   refresh();
}

//ApplicationContext的核心功能几乎都在此方法中实现了,逻辑清晰明了
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {

      //1.准备刷新上下文环境,做准备工作,例如对系统属性及环境变量初始化及验证
      prepareRefresh();
      //2.初始化BeanFactory,并对XML文件进行读取
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      //3.对BeanFactory进行各种功能填充
      prepareBeanFactory(beanFactory);

      try {
         //空实现,留给子类扩展
         postProcessBeanFactory(beanFactory);

         //4.激活各种BeanFactory处理器
         invokeBeanFactoryPostProcessors(beanFactory);

         //5.注册BeanPostProcessor,这里只是注册,真正调用是在getBean的时候
         registerBeanPostProcessors(beanFactory);

         //6.为上下文初始化Message源,国际化处理
         initMessageSource();

         //7.初始化应用消息广播,并放入applicationEventMulticaster中
         initApplicationEventMulticaster();

         //空实现,留给子类实现来初始化其它的bean
         onRefresh();

         //8.在所有注册的bean中查找Listener bean,并注册到广播中
         registerListeners();

         //9.初始化非延迟加载单例
         finishBeanFactoryInitialization(beanFactory);

         //10.完成刷新过程,通知生命处理器刷新过程,同时发出ContextRefreshEvent通知别人
         finishRefresh();
      }
   }
}

3、步骤1:准备刷新上下文环境

//做准备工作,例如对系统属性及环境变量初始化及验证
protected void prepareRefresh() {
   this.startupDate = System.currentTimeMillis();

   synchronized (this.activeMonitor) {
      this.active = true;
   }
   //空实现,留给子类覆盖
   initPropertySources();
   //验证需要的属性文件是否都已经放入环境中
   getEnvironment().validateRequiredProperties();
}

4、步骤2:加载BeanFactory

//经过该函数之后ApplicationContext就有了BeanFactory的全部功能
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   //初始化BeanFactory,并进行XML文件读取,并将得到的beanFactory记录,方便以后获取
   refreshBeanFactory();

   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   return beanFactory;
}
@Override
protected final void refreshBeanFactory() throws BeansException {
   try {
      //直接new DefaultListableBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      //定制BeanFactory,这里已经开始了对BeanFactory的扩展
      customizeBeanFactory(beanFactory);
      //加载BeanDefinition
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         //记录beanFactory
         this.beanFactory = beanFactory;
      }
   }
}
//定制BeanFactory,这里已经开始了对BeanFactory的扩展
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
   //设置是否允许覆盖同名称的不同定义的对象
   if (this.allowBeanDefinitionOverriding != null) {
       beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }
   //设置是否允许bean之间存在循环依赖
   if (this.allowCircularReferences != null) {
       beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }
   //提供了@Qualifier和@Autowired注解的支持
   beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
//加载BeanDefinition
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory){
   //创建XmlBeanDefinitionReader来读取XML配置文件
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   //对XmlBeanDefinitionReader进行环境变量的设置
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   initBeanDefinitionReader(beanDefinitionReader);
   //走到这步之后,后面逻辑和BeanFactory中讲的读取配置文件一样的
   loadBeanDefinitions(beanDefinitionReader);
}

5、步骤3:对BeanFactory进行各种功能填充

prepareBeanFactory(beanFactory);

//进入函数prepareBeanFactory之前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也在此展开
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   beanFactory.setBeanClassLoader(getClassLoader());
   
   //设置beanFactory的表达式语言SpEL处理器,Spring3增加了表达式语言的支持
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());

   //为beanFactory增加一个默认的属性编辑器propertyEditor,在配置文件中可以解析Date(2018-07-27类型)
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   //5.1添加ApplicationContextAwareProcessor处理器,见下面分析
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

   //5.1时已经分析了,这里设置忽略依赖
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   //后面删去了部分代码
}

5.1、添加ApplicationContextAwareProcessor处理器

//ApplicationContextAwareProcessor实现了BeanPostProcessor,在Spring源码分析4之初始化Bean中我们分析过,Spring激活init-method
//前后,会调用BeanPostProcessor的before和after方法,我们看一下ApplicationContextAwareProcessor的这两个方法直接返回,不做处理
public Object postProcessAfterInitialization(Object bean, String beanName) {
   return bean;
}
public Object postProcessBeforeInitialization(final Object bean, String beanName){
   //删去部分代码,留下核心代码
   invokeAwareInterfaces(bean);
   return bean;
}
//实现这些接口的bean在被初始化之后,可以取得对应的资源,相应的这边已经设置了相关属性,因此需要在Spring做依赖注
//入的时候忽略掉它们,见下面代码
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(
               new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
      }
      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);
      }
   }
}

6、步骤4:激活各种BeanFactory处理器

注意是BeanFactoryPostProcessor,不是BeanPostProcessor. BeanFactoryPostProcessor接口和BeanPostProcessor类似,可以对bean的定义
进行处理,Spring IOC容器允许BeanFactoryPostProcessor在容器实例化任何其他的bean之前读取配置元数据,并修改它. 可以实现Ordered接
口来设置BeanFactoryPostProcessor的执行顺序. BeanFactoryPostProcessor的典型应用:PropertyPlaceholderConfigurer. 
PropertyPlaceholderConfigurer间接继承了BeanFactoryPostProcessor接口,当Spring加载任何实现了这个接口的bean的配置时,都会在bean
工厂载入所有bean配置之后执行postProcessBeanFactory方法. 在PropertyResourceConfigurer中实现了postProcessBeanFactory方法,在方
法中分别得到配置,将得到的配置转换为合适的类型,最后将配置内容告诉BeanFactory. 正是通过实现BeanFactoryPostProcessor接口,
BeanFactory会在实例化任何bean之前获取配置信息,从而能够正确解析bean描述文件中的变量引用.
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //待补充
}

7、步骤5:注册BeanPostProcessor

//这里只是注册,而不是调用,真正调用是在bean实例化阶段进行的.BeanFactory中并没有实现后处理器的自动注册,需要手动注册,而在
//ApplicationContext中实现了自动注册功能
registerBeanPostProcessors(beanFactory);
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //获取所有实现了BeanPostProcessor接口的配置文件中配置的bean的id名
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
   //优先级高的
   List priorityOrderedPostProcessors = new ArrayList();
   List internalPostProcessors = new ArrayList();
   //排序的
   List orderedPostProcessorNames = new ArrayList();
   //无序的
   List nonOrderedPostProcessorNames = new ArrayList();

   for (String ppName : postProcessorNames) {
      if (isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
   //对优先级的进行排序并注册
   OrderComparator.sort(priorityOrderedPostProcessors);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   List orderedPostProcessors = new ArrayList();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   
   //对排序的进行排序并注册
   OrderComparator.sort(orderedPostProcessors);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   List nonOrderedPostProcessors = new ArrayList();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   
   //对无序的进行注册
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   OrderComparator.sort(internalPostProcessors);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
}
private void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List postProcessors) {
   for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
   }
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   //先删再加保证了beanPostProcessor的唯一性,其实就是用beanPostProcessors属性记录BeanPostProcessor
   this.beanPostProcessors.remove(beanPostProcessor);
   this.beanPostProcessors.add(beanPostProcessor);
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
   }
}

List beanPostProcessors = new ArrayList();

8、步骤6:为上下文初始化Message源,国际化处理

initMessageSource();

protected void initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //如果容器中配置了messageSource,该属性是硬编码配置的
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
   }
   else {
      //如果没有配置,则new一个临时的MessageSource
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      //注册到容器中
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
   }
}

9、步骤7:初始化应用消息广播,并放入applicationEventMulticaster中

initApplicationEventMulticaster();
protected void initApplicationEventMulticaster() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //如果用户自定义了,则使用用户自定义的
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
   }
   else {
      //否则使用默认的ApplicationEventMulticaster
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
   }
}

10、步骤8:在所有注册的bean中查找Listener bean,并注册到广播中

registerListeners();

protected void registerListeners() {
   
   for (ApplicationListener listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }
   //配置文件注册的监听处理器
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String lisName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(lisName);
   }
}

11、步骤9:初始化非延迟加载单例

finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   //配置ConversionService,也是类型转换器
   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));
   }
   //冻结配置,冻结所有的bean定义,说明注册的bean定义将不会被修改或做任何进一步的处理
   beanFactory.freezeConfiguration();
   //初始化非延迟加载,ApplicationContext的默认行为就是在启动时将所有的非延迟加载的单例提前进行实例化
   beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons() throws BeansException {
   List beanNames;
   synchronized (this.beanDefinitionMap) {
      beanNames = new ArrayList(this.beanDefinitionNames);
   }
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //非抽象,单例,非延迟加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
            boolean isEagerInit = (factory instanceof SmartFactoryBean &&
                                      ((SmartFactoryBean) factory).isEagerInit());
            if (isEagerInit) {
               getBean(beanName);
            }
         }
         else {
            //初始化bean
            getBean(beanName);
         }
      }
   }
}

12、 步骤10:完成刷新过程

//通知生命处理器刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();

protected void finishRefresh() {
   //初始化LifecycleProcessor
   initLifecycleProcessor();

   //启动所有实现了Lifecycle接口的bean
   getLifecycleProcessor().onRefresh();

   //发出ContextRefreshedEvent事件,以保证对应的监听器可以做进一步的处理
   publishEvent(new ContextRefreshedEvent(this));
}

“Spring容器功能扩展的方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


本文名称:Spring容器功能扩展的方法
链接分享:http://csdahua.cn/article/gipjep.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流