框架-spring

          一:spring概要
              簡單來說,Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。
              
          控制反轉——Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。你可以認為IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。
            ◆面向切面——Spring提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。
            ◆容器——Spring包含并管理應用對象的配置和生命周期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創建——基于一個可配置原型(prototype),你的bean可以創建一個單獨的實例或者每次需要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不應該被混同于傳統的重量級的EJB容器,它們經常是龐大與笨重的,難以使用。
            ◆框架——Spring可以將簡單的組件配置、組合成為復雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件里。Spring也提供了很多基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。
            所有Spring的這些特征使你能夠編寫更干凈、更可管理、并且更易于測試的代碼。它們也為Spring中的各種模塊提供了基礎支持。

          二:spring的整個生命周期
              首先說一下spring的整個初始化過程,web應用中創建spring容器有兩種方式:
              第一種:在web.xml里直接配置spring容器,servletcontextlistener
              第二種:通過load-on-startup servlet實現。
              主要就說一下第一種方式:
              spring提供了ServletContextListener的實現類ContextLoaderListener,該類作為listener使用,在創建時自動查找WEB-INF目錄下的applicationContext.xml,該文件是默認查找的,如果只有一個就不需要配置初始化xml參數,如果需要配置,設置contextConfigLocation為application的xml文件即可。可以好好閱讀一下ContextLoaderListener的源代碼,就可以很清楚的知道spring的整個加載過程。
              spring容器的初始化代碼如下:
              /**
               * Initialize the root web application context.
               */
              
          public void contextInitialized(ServletContextEvent event) {
                  
          this.contextLoader = createContextLoader();
                  
          if (this.contextLoader == null) {
                      
          this.contextLoader = this;
                  }
                  
          this.contextLoader.initWebApplicationContext(event.getServletContext());//contextLoader初始化web應用容器

              }
              繼續分析initWebApplicationContext做了什么事情:
              

              
          /**
               * Initialize Spring's web application context for the given servlet context,
               * according to the "{
          @link #CONTEXT_CLASS_PARAM contextClass}" and
               * "{
          @link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params.
               * 
          @param servletContext current servlet context
               * 
          @return the new WebApplicationContext
               * 
          @see #CONTEXT_CLASS_PARAM
               * 
          @see #CONFIG_LOCATION_PARAM
               
          */
              
          public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
                
          //首先創建一個spring的父容器,類似根節點root容器,而且只能是一個,如果已經創建,拋出對應的異常
                  
          if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
                      
          throw new IllegalStateException(
                              
          "Cannot initialize context because there is already a root application context present - " +
                              
          "check whether you have multiple ContextLoader* definitions in your web.xml!");
                  }

                  Log logger 
          = LogFactory.getLog(ContextLoader.class);
                  servletContext.log(
          "Initializing Spring root WebApplicationContext");
                  
          if (logger.isInfoEnabled()) {
                      logger.info(
          "Root WebApplicationContext: initialization started");
                  }
                  
          long startTime = System.currentTimeMillis();

                  
          try {
                      
          // Determine parent for root web application context, if any.
                      ApplicationContext parent = loadParentContext(servletContext);//創建通過web.xml配置的父容器            
          具體里面的代碼是怎么實現的,就不在這里進行詳解了
          // Store context in local instance variable, to guarantee that
                      
          // it is available on ServletContext shutdown.
                      this.context = createWebApplicationContext(servletContext, parent);//主要的創建過程都在改方法內,可以自己去看源代碼
                      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 
          this.context);
                      
          //把spring初始好的容器加載到servletcontext內,相當于servletcontext包含webapplicationcontext
                      ClassLoader ccl 
          = Thread.currentThread().getContextClassLoader();
                      
          if (ccl == ContextLoader.class.getClassLoader()) {
                          currentContext 
          = this.context;
                      }
                      
          else if (ccl != null) {
                          currentContextPerThread.put(ccl, 
          this.context);
                      }

                      
          if (logger.isDebugEnabled()) {
                          logger.debug(
          "Published root WebApplicationContext as ServletContext attribute with name [" +
                                  WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 
          + "]");
                      }
                      
          if (logger.isInfoEnabled()) {
                          
          long elapsedTime = System.currentTimeMillis() - startTime;
                          logger.info(
          "Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
                      }

                      
          return this.context;
                  }
                  
          catch (RuntimeException ex) {
                      logger.error(
          "Context initialization failed", ex);
                      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
                      
          throw ex;
                  }
                  
          catch (Error err) {
                      logger.error(
          "Context initialization failed", err);
                      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
                      
          throw err;
                  }
              }
              
              看到這里基本已經清楚了整個spring容器的加載過程,如果還想了解更加深入,請查看我紅色標注的方法體。

              其次再說一下spring的IOC和AOP使用的場景,由于原理大家都很清楚了,那就說一下它們使用到的地方:
             

              IOC使用的場景:
                  管理bean的依賴關系,目前主流的電子商務網站基本都采用spring管理業務層代碼的依賴關系,包括:淘寶,支付寶,阿里巴巴,百度等公司。
                  

          posted on 2012-02-29 14:45 陳睿 閱讀(1622) 評論(0)  編輯  收藏 所屬分類: 框架


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          <2012年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          26272829123
          45678910

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 攀枝花市| 玛沁县| 彝良县| 江川县| 庆云县| 大城县| 湘阴县| 铜川市| 沧州市| 海口市| 连山| 闵行区| 湘阴县| 清丰县| 日土县| 古蔺县| 石首市| 栾川县| 开化县| 永济市| 乡宁县| 军事| 襄汾县| 延安市| 玉林市| 社旗县| 霸州市| 忻城县| 兴业县| 张家口市| 昌吉市| 龙里县| 原平市| 吉安市| 古蔺县| 镇远县| 富川| 合阳县| 轮台县| 杭锦后旗| 诸暨市|