Spring ApplicationContext 簡解

来源:http://www.cnblogs.com/niejunlei/archive/2016/11/11/6054713.html
-Advertisement-
Play Games

ApplicationContext是對BeanFactory的擴展,實現BeanFactory的所有功能,並添加了事件傳播,國際化,資源文件處理等。 configure locations:(CONFIG_LOCATION_DELIMITERS = ",; \t\n" )分割多個配置文件。 ref ...


ApplicationContext是對BeanFactory的擴展,實現BeanFactory的所有功能,並添加了事件傳播,國際化,資源文件處理等。   configure locations:(CONFIG_LOCATION_DELIMITERS = ",; \t\n" )分割多個配置文件。   refresh()執行所有邏輯。
@Override
public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
        // Allows post-processing of the bean factory in context subclasses.
        postProcessBeanFactory(beanFactory);

        // Invoke factory processors registered as beans in the context.
        invokeBeanFactoryPostProcessors(beanFactory);

        // Register bean processors that intercept bean creation.
        registerBeanPostProcessors(beanFactory);

        // Initialize message source for this context.
        initMessageSource();

        // Initialize event multicaster for this context.
        initApplicationEventMulticaster();

        // Initialize other special beans in specific context subclasses.
        onRefresh();

        // Check for listener beans and register them.
        registerListeners();

        // Instantiate all remaining (non-lazy-init) singletons.
        finishBeanFactoryInitialization(beanFactory);

        // Last step: publish corresponding event.
        finishRefresh();
      }

      catch (BeansException ex) {
        if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
        }

        // Destroy already created singletons to avoid dangling resources.
        destroyBeans();

        // Reset 'active' flag.
        cancelRefresh(ex);

        // Propagate exception to caller.
        throw ex;
      }

      finally {
        // Reset common introspection caches in Spring's core, since we
        // might not ever need metadata for singleton beans anymore...
        resetCommonCaches();
      }
  }
}

prepareRefresh():準備需要刷新的資源。

/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
  this.startupDate = System.currentTimeMillis(); //啟動日期
  this.closed.set(false); //激活標誌
  this.active.set(true); //激活標誌

  if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
  }

  // Initialize any placeholder property sources in the context environment
  initPropertySources(); //供擴展使用

  // Validate that all properties marked as required are resolvable
  // see ConfigurablePropertyResolver#setRequiredProperties
  getEnvironment().validateRequiredProperties(); 

  // Allow for the collection of early ApplicationEvents,
  // to be published once the multicaster is available...
  this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
  initPropertySources()擴展使用如下:
class MyACTX extends ClassPathXmlApplicationContext {

    @Override
    protected void initPropertySources() {
        super.initPropertySources();
        //TODO
    }
}
一般不直接實現ApplicationContext(過多介面),可以繼承ClassPathXmlApplicationContext類,然後重寫相應的方法。做相關操作。   載入BeanFactory:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),(原有功能==配置讀取,解析...)。   prepareBeanFactory():
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  // Tell the internal bean factory to use the context's class loader etc.
  beanFactory.setBeanClassLoader(getClassLoader());
  //表達式語言處理器,Spring3 SpEL表達式,#{xx.xx}支持。
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  //屬性編輯器支持 如處理Date註入
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

  // Configure the bean factory with context callbacks. 
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  //忽略自動裝配的介面
  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

  // BeanFactory interface not registered as resolvable type in a plain factory.
  // MessageSource registered (and found for autowiring) as a bean.
  //設置自動裝配規則
  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  beanFactory.registerResolvableDependency(ApplicationContext.class, this);

  // Detect a LoadTimeWeaver and prepare for weaving, if found.
  //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()));
  }

  // 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());
  }
}

SpEL:Spring Expression Language,運行時構造複雜表達式,存取對象圖屬性,對象方法調用等。SpEL為單獨模塊,只依賴於core模塊。

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
      <property name="driverClassName" value="${dataSource.driverClassName}"/>
      <property name="url" value="${dataSource.url}"/>
      <property name="username" value="${dataSource.username}"/>
      <property name="password" value="${dataSource.password}"/>
      <property name="maxActive" value="${dataSource.maxActive}"/>
      <property name="minIdle" value="${dataSource.minIdle}" />
      <property name="initialSize" value="${dataSource.initialSize}"></property>
      <property name="validationQuery" value="${dataSource.validationQuery}"/>
</bean>
PropertyEditor:自定義屬性編輯器。 Spring中Date類型無法註入,需要註冊相應的屬性編輯器來做處理。Spring處理自定義屬性編輯器類 org.springframework.beans.factory.config.CustomEditorConfigurer
/**
* {@link BeanFactoryPostProcessor} implementation that allows for convenient
* registration of custom {@link PropertyEditor property editors}.
* 註冊
*
*/
public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered {

  protected final Log logger = LogFactory.getLog(getClass());

  private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered

  private PropertyEditorRegistrar[] propertyEditorRegistrars;

  private Map<Class<?>, Class<? extends PropertyEditor>> customEditors;

  ... ...
通過註冊propertyEditorRegistrars或者customEditors。   customEditors(推薦):
自定義Date屬性編輯器MyDateEditor:

class MyDateEditor extends PropertyEditorSupport {

    private String format = "yyyy-MM-dd";

    public void setFormat(String format){
        this.format = format;
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        SimpleDateFormat sp = new SimpleDateFormat(format);
        try{
            this.setValue(sp.parse(text));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

配置:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
    <map>
      <entry key="java.util.Date">
        <bean class="com.xxx.MyDateEditor">
          <property name="format" value="yyyy-MM-dd HH:mm:ss"/>
        </bean>
      </entry>
    </map>
  </property>
</bean>

propertyEditorRegistrars:

自定義Date EditorRegister:

class MyDateRegister implements PropertyEditorRegistrar{
    private String format = "yyyy-MM-dd";

    public void setFormat(String format){
        this.format = format;
    }

    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(format), true));
    }
}

配置:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="propertyEditorRegistrars">
    <list>
      <bean class="com.xxx.MyDateRegister">
        <property name="format" value="yyyy-MM-dd HH:mm:ss"/>
      </bean>
    </list>
  </property>
</bean>
屬性編輯器應用於Bean實例化屬性填充階段。   invokeBeanFactoryPostProcessors():容器級別的bean後置處理。   典型應用:PropertyPlaceholderConfigure。   PlaceholderConfigurerSupport extends PropertyResourceConfigurer .. implements BeanFactoryPostProcessor,間接實現BeanFactoryPostProcessor,會在BeanFacty載入bean配置之後進行屬性文件的處理 :mergeProperties、convertProperties、processProperties,供後續bean的實例化使用。   可以註冊自定義的BeanFactoryPostProcessor。   initMessageSource():初始化消息資源,國際化應用。   兩個message資源文件message_en.properties, message_zh_CN.properties。 添加Spring配置:messageSource id固定。
<!-- 國際化資源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <value>lang/message</value>
    </property>
</bean>

讀取:

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/lang-resource.xml");
String msg = ctx.getMessage("xxx", null, Locale.CHINA);
System.out.println(msg);

nitApplicationEventMulticaster():

/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
  // Register statically specified listeners first.
  for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
  }

  // Do not initialize FactoryBeans here: We need to leave all regular beans
  // uninitialized to let post-processors apply to them!
  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  }

  // Publish early application events now that we finally have a multicaster...
  Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  this.earlyApplicationEvents = null;
  if (earlyEventsToProcess != null) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
        getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
  }
}

... ...


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • webService 可以將應用程式轉換成網路應用程式。是簡單的可共同操作的消息收發框架。 基本的webService平臺是 XML 和 HTTP。 HTTP 是最常用的互聯網協議; XML 是 webService 的基礎,因為可以用於不同平臺和編程語言之間。 webService平臺的元素: S ...
  • LPTSTR、LPCSTR、LPSTR、LPCTSTR、LPWSTR、LPCWSTR: 具體查看:http://blog.csdn.net/yibo_ge/article/details/51058917> http://www.cppblog.com/gezidan/archive/2011/08 ...
  • Qt的網路操作類是非同步(非阻塞的),但有時想做一些阻塞的事情就不方便了,可用如下幾行代碼輕鬆實現: 當然如上方式不支持重定向(301等),因為暫時用不上,如果要支持,還要在return前判斷並迴圈或遞歸。 另外如果出現error,現在的方式會把伺服器返回的錯誤信息直接返回,後面再更新一版,支持判斷錯 ...
  • 上一篇 "《學習AOP之認識一下SpringAOP》" 中大體的瞭解了代理、動態代理及SpringAop的知識。因為寫的篇幅長了點所以還是再寫一篇吧。接下來開始深入一點Spring aop的一些實現機制。 上篇中最後有那段代碼使用了一個ProxyFactory類來完成代理的工作,從而實現了Aop的A ...
  • 結論:通過super調用基類構造方法,必須是子類構造方法中的第一個語句。 子類必須先調用父類的構造方法是因為: 示例中,main方法實際上調用的是: public void println(Object x),這一方法內部調用了String類的valueOf方法。 valueOf方法內部又調用Obj ...
  • 前期準備 搭建solr服務 參考上一篇,搭建solr搜索服務。 添加依賴 maven工程的話,添加如下依賴, 也可以自己導入jar包 在solr安裝目錄下,找到solr-5.5.3\dist\solrj-lib路徑,添加裡面所有的jar包到自己的工程,別忘了在外面的文件夾還有個solr-solrj- ...
  • 前段時間公司要求做一個統計,用swift3.0寫的,因此整理了一下demo,直接上圖 代碼下載地址:https://github.com/minyahui/MYHChartView ...
  • 項目中需要對定義錯誤日誌及時處理, 那麼就需要修改自定義錯誤日誌的輸出方式(寫日誌、發郵件、發簡訊) 一. register_shutdown_function(array('phperror','shutdown_function')); //定義PHP程式執行完成後執行的函數 函數可實現當程式執 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...