玩家必看科普!麻豆人人妻人人妻人人片AV,欧美老妇交乱视频在线观看,久久综合九色综合久99_知乎
<ruby id="fgcka"></ruby>
  • <progress id="fgcka"></progress>
    <tbody id="fgcka"></tbody>
    <dd id="fgcka"></dd>

    1. <dd id="fgcka"></dd>

      <em id="fgcka"></em>
        1. 系統城裝機大師 - 固鎮縣祥瑞電腦科技銷售部宣傳站!

          當前位置:首頁 > 網絡編程 > JavaScript > 詳細頁面

          Spring refresh()源碼解析

          時間:2023-03-15來源:系統城裝機大師作者:佚名

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          public void refresh() throws BeansException, IllegalStateException {
              synchronized(this.startupShutdownMonitor) {
                  // 1. 初始化前的預處理
                  this.prepareRefresh();
                  // 2. 刷新Bean工廠
                  ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
                  // 3. BeanFactory的預處理配置
                  this.prepareBeanFactory(beanFactory);
                  try {
                      // 4. BeanFactory的后置處理
                      this.postProcessBeanFactory(beanFactory);
                      // 5. 執行BeanFactory后置處理器
                      this.invokeBeanFactoryPostProcessors(beanFactory);
                      // 6. 注冊Bean的后置處理器
                      this.registerBeanPostProcessors(beanFactory);
                      // 7. 初始化MessageSource
                      this.initMessageSource();
                      // 8. 初始化事件派發器
                      this.initApplicationEventMulticaster();
                      // 9. 子類的多態onRefresh
                      this.onRefresh();
                      // 10. 注冊監聽器
                      this.registerListeners();
                      // 11. 初始化所有剩下的單例Bean
                      this.finishBeanFactoryInitialization(beanFactory);
                      // 12. 完成容器的創建工作
                      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:初始化前的預處理

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          protected void prepareRefresh() {
              //設置容器啟動時間
              this.startupDate = System.currentTimeMillis();
              //設置容器關閉狀態為false
              this.closed.set(false);
              //設置容器激活狀態為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校驗
              this.getEnvironment().validateRequiredProperties();
              this.earlyApplicationEvents = new LinkedHashSet();
          }

          1.1初始化屬性值

          初始化方法是個模壓方法,由子類重寫

          1
          2
          protected void initPropertySources() {
          }

          Web容器GenericWebApplicationContext重寫了此方法

          1
          2
          3
          4
          5
          6
          7
          8
          protected void initPropertySources() {
              //獲取環境信息
             ConfigurableEnvironment env = getEnvironment();
             //判斷是否是web配置環境
             if (env instanceof ConfigurableWebEnvironment) {
                ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
             }
          }

          最終由StandardServletEnvironment進行初始化

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

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

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          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屬性校驗

          通過占位符解析器校驗資源集合

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

          這里的解析器作為常量在環境被實例化時就被創建出來的,PropertySourcesPropertyResolver是占位符解析器,將數據源中占位符替換成目標值

          校驗是否有需要被占位符修飾的屬性,如果有但是資源中找不到對應屬性的key就會拋出異常

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          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;
             }
          }

          案例: 資源文件

          1
          2
          3
          4
          name=zhansan
          age=${name},10
          encoding=utf-8
          name2=${name}

          測試代碼

          1
          2
          3
          4
          5
          6
          7
          8
          @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
          }

          輸出結果

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

          二、obtainFreshBeanFactory:刷新Bean工廠

          1
          2
          3
          4
          5
          protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
             //2.1刷新Bean工廠
             refreshBeanFactory();
             return getBeanFactory();
          }

          將容器刷新標識改為true,并且設置了工廠序列化id

          1
          2
          3
          4
          5
          6
          7
          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工廠預處理

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
             // 設置BeanFactory的類加載器、表達式解析器等
             beanFactory.setBeanClassLoader(getClassLoader());
             beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
             beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
             // 3.1 添加Aware執行器
             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 自動注入的支持
             beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
             beanFactory.registerResolvableDependency(ResourceLoader.class, this);
             beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
             beanFactory.registerResolvableDependency(ApplicationContext.class, this);
             // 3.3 添加監聽器執行器
             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執行器

          ApplicationContextDProcessor實現了BeanPostProcessor的postProcessBeforeInitialization接口,在所有Bean初始化前會執行當前方法

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
             //判斷Bean是Aware的子類
             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&lt;Object&gt;) () -&gt; {
                   invokeAwareInterfaces(bean);
                   return null;
                }, acc);
             }
             else {
                 //回調執行Aware接口
                invokeAwareInterfaces(bean);
             }
             return bean;
          }

          如果當前Bean是Aware的子類,那么將Bean強轉成Aware類型,通過回調將信息設置到Bean中

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          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:自動注入的支持

          如果過容器中有多個相同接口的實現類,那么在自動注入的時候會注入注冊的實現類

          1
          2
          3
          4
          beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
          beanFactory.registerResolvableDependency(ResourceLoader.class, this);
          beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
          beanFactory.registerResolvableDependency(ApplicationContext.class, this);

          3.3 添加監聽器執行器

          ApplicationListenerDetector主要作用是添加和銷毀監聽器,實現了BeanPostProcessor的postProcessAfterInitialization(Bean實例化之后)方法和DestructionAwareBeanPostProcessor的postProcessBeforeDestruction(Bean銷毀之前)方法

          詳情:https://www.jb51.net/article/277948.htm

          四、BeanFactory的后置處理

          這是個模壓方法,由子類AnnotationConfigServletWebServerApplicationContext實現

          1
          2
          protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
          }

          AnnotationConfigServletWebServerApplicationContext首先調了父類 ServletWebServerApplicationContext 的 postProcessBeanFactory 方法

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
             //4.1后置處理Bean工廠
             super.postProcessBeanFactory(beanFactory);
             if (this.basePackages != null && this.basePackages.length > 0) {
                //basePackages為空不會執行
                this.scanner.scan(this.basePackages);
             }
             if (!this.annotatedClasses.isEmpty()) {
                this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
             }
          }

          4.1 后置處理bean工廠

          父類ServletWebServerApplicationContext首先向Bean工廠中注入了一個執行器

          1
          2
          3
          4
          5
          6
          7
          protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
             //4.1.1注入執行器
             beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
             beanFactory.ignoreDependencyInterface(ServletContextAware.class);
             //4.1.2注冊作用域
             registerWebApplicationScopes();
          }

          4.1.1 WebApplicationContextServletContextAwareProcessor

          WebApplicationContextServletContextAwareProcessor繼承了ServletContextAwareProcessor

          ServletContextAwareProcessor繼承了BeanPostProcessor實現了postProcessBeforeInitialization(Bean初始化前執行)

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          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 注冊web的應用域

          1
          2
          3
          4
          5
          6
          // 所在類及方法:ServletWebServerApplicationContext#registerWebApplicationScopes
             private void registerWebApplicationScopes() {
                    ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory());
                    WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
                    existingScopes.restore();
              }

          ExistingWebApplicationScopes是ServletWebServerApplicationContext類中的一個靜態類

          源碼如下:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          public static class ExistingWebApplicationScopes {
               static {
                Set<String> scopes = new LinkedHashSet<>();
                scopes.add(WebApplicationContext.SCOPE_REQUEST);
                scopes.add(WebApplicationContext.SCOPE_SESSION);
                SCOPES = Collections.unmodifiableSet(scopes);
             }
               // 這是構造方法,大概就是根據SCOPES獲取beanFactory中已經注冊的scope,然后放入scopes
               // 需要注意的是,在上面的方法中,第二行才在向beanFactory中注冊,也就是這時的beanFactory里面沒有request和session這兩個scop
               // 所以這里就完成了beanFactory的賦值。建議打斷點進去看看
             public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
                this.beanFactory = beanFactory;
                for (String scopeName : SCOPES) {
                   Scope scope = beanFactory.getRegisteredScope(scopeName);
                   if (scope != null) {
                      this.scopes.put(scopeName, scope);
                   }
                }
             }
               // 由于上面的方法并沒有值存入scopes,所以這里也就沒執行里面的內容
             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(),這個方法就是向beanFactory注冊web的scope了,源碼如下

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
             registerWebApplicationScopes(beanFactory, null);
          }
           public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
                @Nullable ServletContext sc) {
               // 注冊作用域
             beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());// 注冊request  SCOP
             beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());// 注冊session SCOP
             if (sc != null) {
                ServletContextScope appScope = new ServletContextScope(sc);
                beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // 注冊application SCOP
                // Register as ServletContext attribute, for ContextCleanupListener to detect it.
                sc.setAttribute(ServletContextScope.class.getName(), appScope);
             }
               // 添加依賴項
             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()源碼解析的詳細內容

          分享到:

          相關信息

          系統教程欄目

          欄目熱門教程

          人氣教程排行

          站長推薦

          熱門系統下載

          玩家必看科普!麻豆人人妻人人妻人人片AV,欧美老妇交乱视频在线观看,久久综合九色综合久99_知乎 人人玩人人添人人澡超碰偷拍 青春娱乐视频精品分类官网2 最好最新高清中文字幕 91国自产拍最新2018 欧美精品一区二区三区不卡网 深夜你懂得我的意思2021 宿舍NP乖把腿张开H 网恋奔现一天被要几次 为什么我越叫他越快 学渣各种各样的PLAY 英语课代表下面好软小说 亚洲国产综合在线区尤物 FREE性丰满HD性欧美 我年轻漂亮的继坶BD 最近中文字幕完整免费视频 啦啦啦免费视频卡一卡二 青柠视频在线观看大全 在线天堂WWW在线资源 亚洲国产日本韩国欧美MV 天天学习|久久久久久久精品国产亚洲87 国产K频道分享系统进入口 三个嘴都吃满了还塞满了 JAPONENSIS老师学生JAVAHBB 亚洲精品1卡2卡3卡4卡 樱花草在线社区WWW韩国 好涨水快流出来了快吃动视频 久久AV无码精品人妻出轨