Spring容器功能擴(kuò)展的方法

本篇內(nèi)容介紹了“Spring容器功能擴(kuò)展的方法”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

公司主營業(yè)務(wù):網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出鄉(xiāng)寧免費(fèi)做網(wǎng)站回饋大家。

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、擴(kuò)展功能

if (refresh) {
   refresh();
}

//ApplicationContext的核心功能幾乎都在此方法中實(shí)現(xiàn)了,邏輯清晰明了
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {

      //1.準(zhǔn)備刷新上下文環(huán)境,做準(zhǔn)備工作,例如對(duì)系統(tǒng)屬性及環(huán)境變量初始化及驗(yàn)證
      prepareRefresh();
      //2.初始化BeanFactory,并對(duì)XML文件進(jìn)行讀取
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      //3.對(duì)BeanFactory進(jìn)行各種功能填充
      prepareBeanFactory(beanFactory);

      try {
         //空實(shí)現(xiàn),留給子類擴(kuò)展
         postProcessBeanFactory(beanFactory);

         //4.激活各種BeanFactory處理器
         invokeBeanFactoryPostProcessors(beanFactory);

         //5.注冊BeanPostProcessor,這里只是注冊,真正調(diào)用是在getBean的時(shí)候
         registerBeanPostProcessors(beanFactory);

         //6.為上下文初始化Message源,國際化處理
         initMessageSource();

         //7.初始化應(yīng)用消息廣播,并放入applicationEventMulticaster中
         initApplicationEventMulticaster();

         //空實(shí)現(xiàn),留給子類實(shí)現(xiàn)來初始化其它的bean
         onRefresh();

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

         //9.初始化非延遲加載單例
         finishBeanFactoryInitialization(beanFactory);

         //10.完成刷新過程,通知生命處理器刷新過程,同時(shí)發(fā)出ContextRefreshEvent通知?jiǎng)e人
         finishRefresh();
      }
   }
}

3、步驟1:準(zhǔn)備刷新上下文環(huán)境

//做準(zhǔn)備工作,例如對(duì)系統(tǒng)屬性及環(huán)境變量初始化及驗(yàn)證
protected void prepareRefresh() {
   this.startupDate = System.currentTimeMillis();

   synchronized (this.activeMonitor) {
      this.active = true;
   }
   //空實(shí)現(xiàn),留給子類覆蓋
   initPropertySources();
   //驗(yàn)證需要的屬性文件是否都已經(jīng)放入環(huán)境中
   getEnvironment().validateRequiredProperties();
}

4、步驟2:加載BeanFactory

//經(jīng)過該函數(shù)之后ApplicationContext就有了BeanFactory的全部功能
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   //初始化BeanFactory,并進(jìn)行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,這里已經(jīng)開始了對(duì)BeanFactory的擴(kuò)展
      customizeBeanFactory(beanFactory);
      //加載BeanDefinition
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         //記錄beanFactory
         this.beanFactory = beanFactory;
      }
   }
}
//定制BeanFactory,這里已經(jīng)開始了對(duì)BeanFactory的擴(kuò)展
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
   //設(shè)置是否允許覆蓋同名稱的不同定義的對(duì)象
   if (this.allowBeanDefinitionOverriding != null) {
       beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }
   //設(shè)置是否允許bean之間存在循環(huán)依賴
   if (this.allowCircularReferences != null) {
       beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }
   //提供了@Qualifier和@Autowired注解的支持
   beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
//加載BeanDefinition
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory){
   //創(chuàng)建XmlBeanDefinitionReader來讀取XML配置文件
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   //對(duì)XmlBeanDefinitionReader進(jìn)行環(huán)境變量的設(shè)置
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   initBeanDefinitionReader(beanDefinitionReader);
   //走到這步之后,后面邏輯和BeanFactory中講的讀取配置文件一樣的
   loadBeanDefinitions(beanDefinitionReader);
}

5、步驟3:對(duì)BeanFactory進(jìn)行各種功能填充

prepareBeanFactory(beanFactory);

//進(jìn)入函數(shù)prepareBeanFactory之前,Spring已經(jīng)完成了對(duì)配置的解析,而ApplicationContext在功能上的擴(kuò)展也在此展開
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   beanFactory.setBeanClassLoader(getClassLoader());
   
   //設(shè)置beanFactory的表達(dá)式語言SpEL處理器,Spring3增加了表達(dá)式語言的支持
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());

   //為beanFactory增加一個(gè)默認(rèn)的屬性編輯器propertyEditor,在配置文件中可以解析Date(2018-07-27類型)
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

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

   //5.1時(shí)已經(jīng)分析了,這里設(shè)置忽略依賴
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   //后面刪去了部分代碼
}

5.1、添加ApplicationContextAwareProcessor處理器

//ApplicationContextAwareProcessor實(shí)現(xiàn)了BeanPostProcessor,在Spring源碼分析4之初始化Bean中我們分析過,Spring激活init-method
//前后,會(huì)調(diào)用BeanPostProcessor的before和after方法,我們看一下ApplicationContextAwareProcessor的這兩個(gè)方法直接返回,不做處理
public Object postProcessAfterInitialization(Object bean, String beanName) {
   return bean;
}
public Object postProcessBeforeInitialization(final Object bean, String beanName){
   //刪去部分代碼,留下核心代碼
   invokeAwareInterfaces(bean);
   return bean;
}
//實(shí)現(xiàn)這些接口的bean在被初始化之后,可以取得對(duì)應(yīng)的資源,相應(yīng)的這邊已經(jīng)設(shè)置了相關(guān)屬性,因此需要在Spring做依賴注
//入的時(shí)候忽略掉它們,見下面代碼
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類似,可以對(duì)bean的定義
進(jìn)行處理,Spring IOC容器允許BeanFactoryPostProcessor在容器實(shí)例化任何其他的bean之前讀取配置元數(shù)據(jù),并修改它. 可以實(shí)現(xiàn)Ordered接
口來設(shè)置BeanFactoryPostProcessor的執(zhí)行順序. BeanFactoryPostProcessor的典型應(yīng)用:PropertyPlaceholderConfigurer. 
PropertyPlaceholderConfigurer間接繼承了BeanFactoryPostProcessor接口,當(dāng)Spring加載任何實(shí)現(xiàn)了這個(gè)接口的bean的配置時(shí),都會(huì)在bean
工廠載入所有bean配置之后執(zhí)行postProcessBeanFactory方法. 在PropertyResourceConfigurer中實(shí)現(xiàn)了postProcessBeanFactory方法,在方
法中分別得到配置,將得到的配置轉(zhuǎn)換為合適的類型,最后將配置內(nèi)容告訴BeanFactory. 正是通過實(shí)現(xiàn)BeanFactoryPostProcessor接口,
BeanFactory會(huì)在實(shí)例化任何bean之前獲取配置信息,從而能夠正確解析bean描述文件中的變量引用.
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //待補(bǔ)充
}

7、步驟5:注冊BeanPostProcessor

//這里只是注冊,而不是調(diào)用,真正調(diào)用是在bean實(shí)例化階段進(jìn)行的.BeanFactory中并沒有實(shí)現(xiàn)后處理器的自動(dòng)注冊,需要手動(dòng)注冊,而在
//ApplicationContext中實(shí)現(xiàn)了自動(dòng)注冊功能
registerBeanPostProcessors(beanFactory);
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //獲取所有實(shí)現(xiàn)了BeanPostProcessor接口的配置文件中配置的bean的id名
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
   //優(yōu)先級(jí)高的
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
   //排序的
   List<String> orderedPostProcessorNames = new ArrayList<String>();
   //無序的
   List<String> nonOrderedPostProcessorNames = new ArrayList<String>();

   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);
      }
   }
   //對(duì)優(yōu)先級(jí)的進(jìn)行排序并注冊
   OrderComparator.sort(priorityOrderedPostProcessors);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   
   //對(duì)排序的進(jìn)行排序并注冊
   OrderComparator.sort(orderedPostProcessors);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   
   //對(duì)無序的進(jìn)行注冊
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

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

   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
}
private void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
   for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
   }
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   //先刪再加保證了beanPostProcessor的唯一性,其實(shí)就是用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<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

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一個(gè)臨時(shí)的MessageSource
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      //注冊到容器中
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
   }
}

9、步驟7:初始化應(yīng)用消息廣播,并放入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 {
      //否則使用默認(rèn)的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);
   }
   //配置文件注冊的監(jiān)聽處理器
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String lisName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(lisName);
   }
}

11、步驟9:初始化非延遲加載單例

finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   //配置ConversionService,也是類型轉(zhuǎn)換器
   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));
   }
   //凍結(jié)配置,凍結(jié)所有的bean定義,說明注冊的bean定義將不會(huì)被修改或做任何進(jìn)一步的處理
   beanFactory.freezeConfiguration();
   //初始化非延遲加載,ApplicationContext的默認(rèn)行為就是在啟動(dòng)時(shí)將所有的非延遲加載的單例提前進(jìn)行實(shí)例化
   beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons() throws BeansException {
   List<String> beanNames;
   synchronized (this.beanDefinitionMap) {
      beanNames = new ArrayList<String>(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:完成刷新過程

//通知生命處理器刷新過程,同時(shí)發(fā)出ContextRefreshEvent通知?jiǎng)e人
finishRefresh();

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

   //啟動(dòng)所有實(shí)現(xiàn)了Lifecycle接口的bean
   getLifecycleProcessor().onRefresh();

   //發(fā)出ContextRefreshedEvent事件,以保證對(duì)應(yīng)的監(jiān)聽器可以做進(jìn)一步的處理
   publishEvent(new ContextRefreshedEvent(this));
}

“Spring容器功能擴(kuò)展的方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

本文題目:Spring容器功能擴(kuò)展的方法
文章路徑:http://bm7419.com/article48/gipjep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、品牌網(wǎng)站建設(shè)、建站公司網(wǎng)站改版、品牌網(wǎng)站設(shè)計(jì)、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)