亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring?refresh()源碼解析

 更新時(shí)間:2023年03月14日 14:49:04   作者:無(wú)名之輩J  
這篇文章主要為大家介紹了Spring?refresh()源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

public void refresh() throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        // 1. 初始化前的預(yù)處理
        this.prepareRefresh();
        // 2. 刷新Bean工廠(chǎng)
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        // 3. BeanFactory的預(yù)處理配置
        this.prepareBeanFactory(beanFactory);
        try {
            // 4. BeanFactory的后置處理
            this.postProcessBeanFactory(beanFactory);
            // 5. 執(zhí)行BeanFactory后置處理器
            this.invokeBeanFactoryPostProcessors(beanFactory);
            // 6. 注冊(cè)Bean的后置處理器
            this.registerBeanPostProcessors(beanFactory);
            // 7. 初始化MessageSource
            this.initMessageSource();
            // 8. 初始化事件派發(fā)器
            this.initApplicationEventMulticaster();
            // 9. 子類(lèi)的多態(tài)onRefresh
            this.onRefresh();
            // 10. 注冊(cè)監(jiān)聽(tīng)器
            this.registerListeners();
            // 11. 初始化所有剩下的單例Bean
            this.finishBeanFactoryInitialization(beanFactory);
            // 12. 完成容器的創(chuàng)建工作
            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 {
            // 13. 清除緩存
            this.resetCommonCaches();
        }
    }
}

一、prepareRefresh:初始化前的預(yù)處理

protected void prepareRefresh() {
    //設(shè)置容器啟動(dòng)時(shí)間
    this.startupDate = System.currentTimeMillis();
    //設(shè)置容器關(guān)閉狀態(tài)為false
    this.closed.set(false);
    //設(shè)置容器激活狀態(tài)為true
    this.active.set(true);
    if (this.logger.isDebugEnabled()) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Refreshing " + this);
        } else {
            this.logger.debug("Refreshing " + this.getDisplayName());
        }
    }
    //1.1初始化屬性資源
    this.initPropertySources();
    //1.2校驗(yàn)
    this.getEnvironment().validateRequiredProperties();
    this.earlyApplicationEvents = new LinkedHashSet();
}

1.1初始化屬性值

初始化方法是個(gè)模壓方法,由子類(lèi)重寫(xiě)

protected void initPropertySources() {
}

Web容器GenericWebApplicationContext重寫(xiě)了此方法

protected void initPropertySources() {
    //獲取環(huán)境信息
   ConfigurableEnvironment env = getEnvironment();
   //判斷是否是web配置環(huán)境
   if (env instanceof ConfigurableWebEnvironment) {
      ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
   }
}

最終由StandardServletEnvironment進(jìn)行初始化

public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
//使用web容器工具初始化 
WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
}

把 Servlet 的一些初始化參數(shù)放入IOC容器中

public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    Assert.notNull(sources, "'propertySources' must not be null");
    String name = "servletContextInitParams";
    if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletContextPropertySource(name, servletContext));
    }
    name = "servletConfigInitParams";
    if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
    }
}

1.2屬性校驗(yàn)

通過(guò)占位符解析器校驗(yàn)資源集合

public void validateRequiredProperties() throws MissingRequiredPropertiesException {
   this.propertyResolver.validateRequiredProperties();
}

這里的解析器作為常量在環(huán)境被實(shí)例化時(shí)就被創(chuàng)建出來(lái)的,PropertySourcesPropertyResolver是占位符解析器,將數(shù)據(jù)源中占位符替換成目標(biāo)值

校驗(yàn)是否有需要被占位符修飾的屬性,如果有但是資源中找不到對(duì)應(yīng)屬性的key就會(huì)拋出異常

public void validateRequiredProperties() {
   MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
   for (String key : this.requiredProperties) {
      if (this.getProperty(key) == null) {
         ex.addMissingRequiredProperty(key);
      }
   }
   if (!ex.getMissingRequiredProperties().isEmpty()) {
      throw ex;
   }
}

案例: 資源文件

name=zhansan
age=${name},10
encoding=utf-8
name2=${name}

測(cè)試代碼

    @Test
    public void test1() throws Exception {
        //省略propertySources
        PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(getPropertySources());
        System.out.println(propertyResolver.getProperty("age"));    
        System.out.println(propertyResolver.getProperty("encoding"));
        System.out.println(propertyResolver.resolvePlaceholders("must be encoding ${encoding}"));  //輸出must be encoding gbk
    }

輸出結(jié)果

10,zhansan
utf-8
must be encoding utf-8

二、obtainFreshBeanFactory:刷新Bean工廠(chǎng)

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   //2.1刷新Bean工廠(chǎng)
   refreshBeanFactory();
   return getBeanFactory();
}

將容器刷新標(biāo)識(shí)改為true,并且設(shè)置了工廠(chǎng)序列化id

protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}

三、prepareBeanFactory:Bean工廠(chǎng)預(yù)處理

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // 設(shè)置BeanFactory的類(lèi)加載器、表達(dá)式解析器等
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
   // 3.1 添加Aware執(zhí)行器
   beanFactory.addBeanPostProcessor(new ApplicationContextDProcessor(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);
   // 3.2 自動(dòng)注入的支持
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);
   // 3.3 添加監(jiān)聽(tīng)器執(zhí)行器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   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()));
   }
   // Register default environment beans.
   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());
   }
}

3.1 ApplicationContextDProcessor:Aware執(zhí)行器

ApplicationContextDProcessor實(shí)現(xiàn)了BeanPostProcessor的postProcessBeforeInitialization接口,在所有Bean初始化前會(huì)執(zhí)行當(dāng)前方法

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   //判斷Bean是Aware的子類(lèi)
   if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
         bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
         bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
      return bean;
   }
   AccessControlContext acc = null;
   if (System.getSecurityManager() != null) {
      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
   }
   if (acc != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareInterfaces(bean);
         return null;
      }, acc);
   }
   else {
       //回調(diào)執(zhí)行Aware接口
      invokeAwareInterfaces(bean);
   }
   return bean;
}

如果當(dāng)前Bean是Aware的子類(lèi),那么將Bean強(qiáng)轉(zhuǎn)成Aware類(lèi)型,通過(guò)回調(diào)將信息設(shè)置到Bean中

private void invokeAwareInterfaces(Object bean) {
   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);
   }
}

3.2 registerResolvableDependency:自動(dòng)注入的支持

如果過(guò)容器中有多個(gè)相同接口的實(shí)現(xiàn)類(lèi),那么在自動(dòng)注入的時(shí)候會(huì)注入注冊(cè)的實(shí)現(xiàn)類(lèi)

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

3.3 添加監(jiān)聽(tīng)器執(zhí)行器

ApplicationListenerDetector主要作用是添加和銷(xiāo)毀監(jiān)聽(tīng)器,實(shí)現(xiàn)了BeanPostProcessor的postProcessAfterInitialization(Bean實(shí)例化之后)方法和DestructionAwareBeanPostProcessor的postProcessBeforeDestruction(Bean銷(xiāo)毀之前)方法

詳情:http://chabaoo.cn/article/277948.htm

四、BeanFactory的后置處理

這是個(gè)模壓方法,由子類(lèi)AnnotationConfigServletWebServerApplicationContext實(shí)現(xiàn)

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

AnnotationConfigServletWebServerApplicationContext首先調(diào)了父類(lèi) ServletWebServerApplicationContext 的 postProcessBeanFactory 方法

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   //4.1后置處理Bean工廠(chǎng)
   super.postProcessBeanFactory(beanFactory);
   if (this.basePackages != null && this.basePackages.length > 0) {
      //basePackages為空不會(huì)執(zhí)行
      this.scanner.scan(this.basePackages);
   }
   if (!this.annotatedClasses.isEmpty()) {
      this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
   }
}

4.1 后置處理bean工廠(chǎng)

父類(lèi)ServletWebServerApplicationContext首先向Bean工廠(chǎng)中注入了一個(gè)執(zhí)行器

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   //4.1.1注入執(zhí)行器
   beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(ServletContextAware.class);
   //4.1.2注冊(cè)作用域
   registerWebApplicationScopes();
}

4.1.1 WebApplicationContextServletContextAwareProcessor

WebApplicationContextServletContextAwareProcessor繼承了ServletContextAwareProcessor

ServletContextAwareProcessor繼承了BeanPostProcessor實(shí)現(xiàn)了postProcessBeforeInitialization(Bean初始化前執(zhí)行)

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    //注入ServletContext
   if (getServletContext() != null && bean instanceof ServletContextAware) {
      ((ServletContextAware) bean).setServletContext(getServletContext());
   }
   //注入ServletConfig
   if (getServletConfig() != null && bean instanceof ServletConfigAware) {
      ((ServletConfigAware) bean).setServletConfig(getServletConfig());
   }
   return bean;
}

4.1.2 registerWebApplicationScopes 注冊(cè)web的應(yīng)用域

// 所在類(lèi)及方法:ServletWebServerApplicationContext#registerWebApplicationScopes
   private void registerWebApplicationScopes() {
          ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory());
          WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
          existingScopes.restore();
    }

ExistingWebApplicationScopes是ServletWebServerApplicationContext類(lèi)中的一個(gè)靜態(tài)類(lèi)

源碼如下:

    public static class ExistingWebApplicationScopes {
        static {
         Set<String> scopes = new LinkedHashSet<>();
         scopes.add(WebApplicationContext.SCOPE_REQUEST);
         scopes.add(WebApplicationContext.SCOPE_SESSION);
         SCOPES = Collections.unmodifiableSet(scopes);
      }
        // 這是構(gòu)造方法,大概就是根據(jù)SCOPES獲取beanFactory中已經(jīng)注冊(cè)的scope,然后放入scopes
        // 需要注意的是,在上面的方法中,第二行才在向beanFactory中注冊(cè),也就是這時(shí)的beanFactory里面沒(méi)有request和session這兩個(gè)scop
        // 所以這里就完成了beanFactory的賦值。建議打斷點(diǎn)進(jìn)去看看
      public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
         this.beanFactory = beanFactory;
         for (String scopeName : SCOPES) {
            Scope scope = beanFactory.getRegisteredScope(scopeName);
            if (scope != null) {
               this.scopes.put(scopeName, scope);
            }
         }
      }
        // 由于上面的方法并沒(méi)有值存入scopes,所以這里也就沒(méi)執(zhí)行里面的內(nèi)容
      public void restore() {
         this.scopes.forEach((key, value) -> {
            if (logger.isInfoEnabled()) {
               logger.info("Restoring user defined scope " + key);
            }
            this.beanFactory.registerScope(key, value);
         });
      }
   }

WebApplicationContextUtils.registerWebApplicationScopes(),這個(gè)方法就是向beanFactory注冊(cè)web的scope了,源碼如下

    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
      registerWebApplicationScopes(beanFactory, null);
   }
    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
         @Nullable ServletContext sc) {
        // 注冊(cè)作用域
      beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());// 注冊(cè)request  SCOP
      beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());// 注冊(cè)session SCOP
      if (sc != null) {
         ServletContextScope appScope = new ServletContextScope(sc);
         beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // 注冊(cè)application SCOP
         // Register as ServletContext attribute, for ContextCleanupListener to detect it.
         sc.setAttribute(ServletContextScope.class.getName(), appScope);
      }
        // 添加依賴(lài)項(xiàng)
      beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
      beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
      beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
      beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
      if (jsfPresent) {
         FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
      }
   }

以上就是Spring refresh()源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Spring refresh()的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot接收參數(shù)的8種方式示例詳解

    SpringBoot接收參數(shù)的8種方式示例詳解

    這篇文章主要介紹了SpringBoot接收參數(shù)的8種方式,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • RestTemplate設(shè)置超時(shí)時(shí)間及返回狀態(tài)碼非200處理

    RestTemplate設(shè)置超時(shí)時(shí)間及返回狀態(tài)碼非200處理

    這篇文章主要為大家介紹了RestTemplate設(shè)置超時(shí)時(shí)間及返回狀態(tài)碼非200處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Java 包裝類(lèi)型及易錯(cuò)陷阱詳解

    Java 包裝類(lèi)型及易錯(cuò)陷阱詳解

    這篇文章主要介紹了Java 包裝類(lèi)型及易錯(cuò)陷阱詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié)

    Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié)

    Feign 的英文表意為“假裝,偽裝,變形”, 是一個(gè)http請(qǐng)求調(diào)用的輕量級(jí)框架,可以以Java接口注解的方式調(diào)用Http請(qǐng)求,而不用像Java中通過(guò)封裝HTTP請(qǐng)求報(bào)文的方式直接調(diào)用。接下來(lái)通過(guò)本文給大家分享Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié),感興趣的朋友一起看看吧
    2021-05-05
  • RabbitMQ中的Connection和Channel信道詳解

    RabbitMQ中的Connection和Channel信道詳解

    這篇文章主要介紹了RabbitMQ中的Connection和Channel信道詳解,信道是建立在 Connection 之上的虛擬連接,RabbitMQ 處理的每條 AMQP 指令都是通過(guò)信道完成的,需要的朋友可以參考下
    2023-08-08
  • SSH框架網(wǎng)上商城項(xiàng)目第5戰(zhàn)之商品類(lèi)別級(jí)聯(lián)查詢(xún)和分頁(yè)功能

    SSH框架網(wǎng)上商城項(xiàng)目第5戰(zhàn)之商品類(lèi)別級(jí)聯(lián)查詢(xún)和分頁(yè)功能

    SSH框架網(wǎng)上商城項(xiàng)目第5戰(zhàn)之商品類(lèi)別級(jí)聯(lián)查詢(xún)和分頁(yè)功能,寫(xiě)一下CategoryServiceImpl實(shí)現(xiàn)類(lèi),完成數(shù)據(jù)庫(kù)的級(jí)聯(lián)查詢(xún),感興趣的小伙伴們可以參考一下
    2016-05-05
  • java代理模式(靜態(tài)代理、動(dòng)態(tài)代理、cglib代理)

    java代理模式(靜態(tài)代理、動(dòng)態(tài)代理、cglib代理)

    代理(Proxy)是一種設(shè)計(jì)模式,提供了對(duì)目標(biāo)對(duì)象另外的訪(fǎng)問(wèn)方式;這篇文章主要介紹了Java 中的三種代理模式,需要的朋友可以參考下,希望能給你帶來(lái)幫助
    2021-07-07
  • Java的無(wú)參構(gòu)造函數(shù)用法實(shí)例分析

    Java的無(wú)參構(gòu)造函數(shù)用法實(shí)例分析

    這篇文章主要介紹了Java的無(wú)參構(gòu)造函數(shù)用法,結(jié)合實(shí)例形式分析了java無(wú)參構(gòu)造函數(shù)基本原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • servlet之cookie簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    servlet之cookie簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Cookie技術(shù)誕生以來(lái),它就成了廣大網(wǎng)絡(luò)用戶(hù)和Web開(kāi)發(fā)人員爭(zhēng)論的一個(gè)焦點(diǎn)。下面這篇文章主要給大家介紹了關(guān)于servlet之cookie簡(jiǎn)介的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-07-07
  • Java8常用的新特性詳解

    Java8常用的新特性詳解

    這篇文章主要介紹了Java8常用的新特性詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java8新特性的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評(píng)論