1. 程式人生 > >Spring初級學習小結

Spring初級學習小結

1.Spring是一個從實際開發中抽取出來的框架,它完成了大量開發中的通用步驟,留給開發者的僅僅是與特定應用相關的部分,從而大大地提高了企業應用的開發效率

     Spring 具有如下優點:

         > 低侵入式設計, 程式碼的汙染極低。

          > 獨立於各種應用伺服器, 基於Spring 框架的應用,可以真正實現Write Once 、Run Anywhere的承諾。

     

     > SpringDI 容器降低了業務物件替換的複雜性,提高了元件之間的解耦

          > SpringAOP 支援允許將一些通用任務如安全、事務、日誌等進行集中式處理,從而提供

了更好的複用。

          > SpringORMDAO 提供了與第三方持久層框架的良好整合, 並簡化了底層的資料庫訪間。

          

> Spring 的高度開放性,並不強制應用完全依賴於Spring, 開發者可自由選用Spring 框架的部分或全部。

2. Spring框架的下載地址:---到2017.1.3最新版為4.3.5

     http://repo.springsource.org/libs-release-local/org/springframework/spring/

     Spring API 的線上地址:

     http://docs.spring.io/spring/docs/current/javadoc-api/

     Spring 涉及的相關jar包下載:

     http://commons.apache.org/proper/commons-logging/download_logging.cgi

     Eclispe中安裝Spring tools 套件外掛:

     Spring Tool Suite(STS) for Eclispe 3.8.3.RELEASE

     安裝此外掛後可以方便的建立和修改Spring的配置檔案,並且支援提示的功能。

     Properties.Editer

3.Spring專案的開發步驟:

     A.建立一個動態Web專案或者Java專案;

     B.匯入Spring框架的相關jar包,若是Java專案需要加入到build path中,若是Web專案需要複製到WEB-INF下的lib資料夾中。

     C.建立spring配置檔案applicationContext.xml,以及其他的配置檔案,比如log4j的配置檔案。

 

4.當我們使用Spring 框架時, 必須使用Spring Core Container (即Spring 容器),它代表了Spring 框架的核心機制, Spring Core Container 主要由org.springframework.core 、

orgspringfamework.beans 和org.springframework.context、org.springframework.expression 四個包及其子包組成,主要提供Spring IoC 容器支援。

     控制反轉(Inversion of Control, IoC)###從呼叫者角度看

          使用Spring框架之後,呼叫者無需主動獲取被依賴的物件,呼叫者只要被動接受Spring容器為呼叫者的成員變數賦值即可(只要配置一個<property.../> 子元素,Spring就會執行對應的Setter方法為呼叫者的成員變數賦值)。使用Spring框架之後,呼叫者獲取被依賴物件的方式,由原來的主動獲取變成了被動接受----Rod Johnson將這種方式稱為控制反轉!

     依賴注入(Denpendency Injection, DI)###從Spring容器看

          Spring容器負責將被依賴物件賦值給呼叫者的成員變數----相當於為呼叫者注入它依賴的例項,Martine Fowler 稱之為依賴注入

          IoC和DI,其實意義完全相同,是同一個行為的兩種表達,只是描述的角度不同而已!

5.Spring容器,建立、管理Java類,

          要被管理的Bean配置有哪些配置方式?

          ---XML的配置檔案和註解方式

          如何初始化容器?

          ---使用ApplicationContext介面的兩個實現類

          如何從容器中獲取Bean?

          ---使用ApplicationContext介面的getBean()方法。

6.將Java類放入Spring容器中有兩種方式:

          A.使用XML配置檔案的方式

          B.使用註解的配置方式

7.使用XML配置檔案的方式:在applicationContext.xml中

    1. 使用<bean>標籤在<beans>標籤中定義/宣告一個bean;支援的屬性:

    1. 使用classs屬性指定要例項化的物件是什麼型別,值通常為:包名.類名;
    2. 使用id屬性,指定物件例項化後叫什麼名字,以便後面獲取時引用;

                          <bean id="dao" class="dao.impl.UserDaoImpl" />

    1. 使用<property>標籤為bean物件的屬性賦值;基本型別和String型別使用value,引用型別使用ref
<bean id="service" class="service.impl.UserServiceImpl">

<property name="dao" ref="dao"></property>

</bean>

對於內部bean

對於listset、陣列的<property>標籤的配置是一樣的,如:

<!-- 注入List型別 -->

<property name="list">

<list>

<!-- 定義List中的元素 -->

<value>乒乓球</value>

</list>

</property>

 

    1. 可以使用<constructor-arg ref="...">,在物件初始化時呼叫含有引數的建構函式,完成屬性的賦值
<bean id="boyConstructor" class="com.ddb.spring.set.BoyConstructor">

<!-- 通過構造方法注入物件 -->

<constructor-arg ref="chinaGirlFriend" />

</bean>

        f.可以使用p名稱空間,來為屬性賦值:

 

8.使用註解的配置方式:

    使用註解標註要放入Spring容器的類;使用的註解可以是:

        @Component 標註一個普通的Spring Bean類

        @Controller 標註一個控制器元件類

        @Service 標註一個業務邏輯元件類

        @Repository 標註一個DAO元件類

    使用@Autowired為Java類的引用屬性自動注入值;

        @Autowired

        private UsaGirlFriend usaGirlFriend;

    使用@Resource為方法或屬性注入需要的元件;

        ---此註解並不屬於Spring框架,而是屬於javax的

        @Resource註解,支援nametype屬性,例如:

    XML的配置檔案中配置元件自動掃描,將使用註解的Java類加入Spring容器中:

        ---這一步必須有!

        <!-- 自動掃描包含註解的包 -->

        <context:component-scan base-package="com.ddb.spring.auto" />

9.如何在Java中初始化Spring容器

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        //以applicationContext.xml為引數初始化Spring容器上下文

        說明:ApplicationContext 是Spring容器最常用的介面,有兩個實現類如下:

        ClassPathXmlApplicationContext:從類載入路徑下搜尋配置檔案,並根據配置檔案來建立Spring容器; ---這種方式使用    更改普遍一些。

        FileSystemXmlApplicationContext:從檔案系統的相對路徑或絕對路徑,去搜索配置檔案,並根據...

10.獲取Spring容器中的Bean

        //獲取容器中指定的idBean例項

        UserService userService = (UserService) ctx.getBean("service");

        主要有兩個方法:

        Object getBean(String id) :根據容器中Bean的id來獲取指定的Bean,獲取Bean之後需要進行強制型別轉換

        T getBean(String id,Class<T> requiredType) :根據容器中Bean的id來獲取指定的Bean,但是方法帶了一個泛型引數,獲取    Bean之後不需要進行強制型別轉換

11..AOP ( Aspect Orient Programming),也就是面向切面程式設計,在Java EE應用中,常常通過AOP 來處理一些具有橫切性質的系統級服務,如事務管理、安全檢查、快取、物件池管理等, AOP 已經成為一種非常常用的解決方案。

12.如何理解AOP:

        A.在沒有AOP的時候,可能會有這樣的場景,在N多個方法中有相同功能程式碼,比如安全檢查,但是存在問題是---重複,修改困難容易出現不一致,新方法還需要這些重複的程式碼!

        B.重複的問題,我可以將相同的程式碼抽取出來,統一呼叫抽取出來的方法來解決,但是存在的問題是---每個方法都顯示地知道了自己呼叫抽出來的方法,並且如果我們需要再增加日誌的操作等,就要再增加顯示呼叫日誌的函式,再增加許可權檢查,事務檢查,你會發現顯示呼叫就會越來越多。

        C.AOP就可以解決上面的問題,通過切面和切入點織入需要處理的操作,而原來的業務元件卻毫無察覺

        AOP的原理和Listener有些類似,可以理解監聽的方法被呼叫,從而觸發了一些前置操作或者後置操作等

13.AspectJ 的作用:開發者無須修改原始碼,但又可以為元件的方法新增新的功能!

14.AOP的實現分為兩類:

        靜態AOP實現:編譯階段對程式進行修改,即實現對目標物件的增強,以AspectJ為代表;

        動態AOP實現:在執行階段動態生成AOP代理,以實現對目標物件的增強,以SpringAOP為代表。

15.AOP 框架具有如下兩個特徵

        > 各步驟之間的良好隔離性

        > 原始碼無關性

16.AOP程式設計,其中需要程式設計師參與的只有三個部分

        > 定義普通業務元件。

        > 定義切入點, 一個切入點可能橫切多個業務元件。

        > 定義增強處理,增強處理就是在AOP 框架為普通業務元件織入的處理動作。

17.Spring 有如下兩種選擇來定義切入點和增強處理。

        > 基於XML 配置檔案的管理方式:使用Spring 配置檔案來定義切入點和增強處理。

        > 基於註解的“零配置”方式:使用@Aspect 、@Pointcut 等註解來標註切入點和增強處理。

18.Spring AOP基於XML配置的方式:

        在Spring 的配置檔案中, 所有切面、切入點和增強處理都必須定義在<aop:config>標籤元素內部。<beans ... />元素下可以包含多個<aop:config>元素, 一個<aop:config>可以包含pointcut 、advisor 和aspect 元素, 且這三個元素必須按照此順序來定義。

    A .定義切面:---使用<aop:aspect>標籤

    B .配置增強處理:

        使用的標籤有:

            <aop:before>、<aop:after>、<aop:after-returning>、

            <aop:after-throwing>、<aop:around>

            上面這些元素都不支援使用子元素, 但通常可指定如下屬性。

            > pointcut: 指定一個切入表示式, Spring 將在匹配該表示式的連線點時織入該增強處理。

            > pointcut-ref: 指定一個已經存在的切入點名稱, 通常pointcut 和pointcut-ref 兩個屬性

            只需使用其中之一。

            > method : 該屬性指定一個方法名, 指定切面Bean 的該方法將作為增強處理。

            > throwing : 只對<aop:after-throwing>元素有效, 用於指定一個形參名,AfteThrowing 增強處理方法可通過該形參訪問目標方法所丟擲的異常。

            > returning : 該屬性只對<aop:after-returning>元素有效,用於指定一個形參名, AfterReturning增強處理方法可通過該形參訪問目標方法的返回值。

    C.配置切入點:---使用<aop:pointcut>標籤

        標籤中可以使用的子標籤,可以通過自動提示列出來!

        例如:

<bean id="dao" class="dao.impl.UserDaoImpl" />

<bean id="service" class="service.impl.UserServiceImpl">

    <property name="dao" ref="dao"></property>

</bean>

<bean id="loggerBefore" class="aop.LoggerBefore" />

<bean id="loggerAfterReturning" class="aop.LoggerAfterReturning" />

<aop:config>

   <aop:pointcut id="pointcut"

       expression="execution(public void addNewUser(entity.User))" />

   <aop:advisor pointcut-ref="pointcut" advice-ref="loggerBefore"/>

   <aop:advisor pointcut-ref="pointcut" advice-ref="loggerAfterReturning"/>

</aop:config>

19.Spring AOP基於註解的配置方式:

    為了啟用Spring 對註解@AspetJ 切面配置的支援

    方式一:使用Spring 的XML Schema 配置方式,在Spring的applicationContext.xml檔案中的<beans>中增加:

        <!-- 啟動@AspectJ 支援 -->

        <aop : aspectj-autoproxy/>

    方式二:使用一個Bean後處理器,在Spring 配置檔案中增加如下片段來啟用@AspecJ 支援。

        <!-- 啟動@AspectJ 支援 -->

        <bean class="org.springframework.aop.aspectj.annotation.

        AnnotationAwareAspectJAutoProxyCreator" />

上面的配置檔案中的 AnnotationAwareAspecUAutoProxyCreator是一個Bean 後處理器,該Bean 後處理旅將會為容器中Bean 生成AOP 代理,為了在Spring 應用中啟動@AspectJ 支援,還需要在應用的類載入路徑中增加兩個AspectJ 庫:aspectjweaver.jar 和aspectjrt.jar

    A.定義切面:使用註解:@AspectJ ,直接加到類的上一行

    使用@Aspect 標註一個Java 類,該Java 類將會作為切面Bean,當我們使用@Aspect 來修飾一個Java 類之後, Spring 將不會把該Bean 當成級件Bean 處理,因此負責自動熠強的後處理Bean 將會略過該Bean,不會對該Bean 進行任何增強處理。

    B.定義增強處理:註解都是加在方法之上

    @Before --只能在目標方法執行之前織入增強

        通常需要指定一個value 屬性值,該屬性值指定一個切入點表示式〈既可以是一個

己有的切入點, 也可以直接定義切入點表示式),用於指定該增強處理將被織入哪些切入點。

        Before 處理無法阻止目標方法的執行, Before 增強處理執行時,目標方法還未獲得執行的機會,所以Before 增強處理無法訪問目標方法的返回值. 若要阻止目標方法執行,可以通過拋異常來實現

        例如:

        @Before("execution(* org.crazyit.app.service.impl .*.*(..))")

        @Before 註解 直接指定了切入點表示式,指定匹org.crazyit.app.service.impl 包下所有類的所有方法的執行作為切入點。

    @AfterReturning 在目標方法正常完成後被織入

        例如:

        @AfterReturning(returning="rvt",pointcut="execution(* org.crazyit.app.service.impl .*.*(..))") //value屬性與pointcut屬性作用一樣

            public void log(Object rvt)

            如果上面的log()方法中定義rvt 形參的型別是String,則該切入點只匹配lee 包下返回值型別為String 的所有方法.

            可以訪問目標方法的返回值,但是不可以改變返回值

    @AfterThrowing 主要用於處理程式中未處理的異常

            @AfterThrowing( throwing="ex"

            ,pointcut="execution(* org.crazyit.app.service.impl .*.*(..))") //value屬性與pointcut屬性作用一樣

            public void doRecoveryActions (Throwable ex)

            使用throwing 屬性還有一個額外的作用:它可用於限定切入點只匹配指定型別的異

            常--假如如在上面的doRecoveryActions()方法中定義了ex 形參的型別是NullPointer-

            Exception ,則該切入點只匹配丟擲NullPointerException 異常的情況. 上面doRecoveryActions()方法的ex 形參型別是Throwable ,這表明該切入點可匹配丟擲任何異常的情況. AfterThrowing 處理雖然處理了該異常,但它不能完全處理異常,異常依然會傳播到上一級呼叫者

            @After 不管目標方法如何結束,成功完成或者異常終止,它都會被織入;這種增強通常用於釋放資源。

                @After("execution(* org.crazyit.app.service.impl .*.*(..))")

                After 增強處理的作用非常類似於異常處理中finally 塊的作用一一無論如何,它總會在方法執行結束之後被織入,因此特別適用於進行資源回收。

    @Around 增強的超級大Boss

            @Around("execution(* org.crazyit.app.service.impl .*.*(..))")

            public void save(ProceedingJoinPoint pjp)

 

            Around 增強處理甚至可以決定目標方法在什麼時候執行,如何執行,甚至可以完全阻止目標方法的執行;可以改變執行目標方法的引數值;也可改變執行目標方法之後的返回值。

            Around 增強處理的功能雖然強大,但通常需要線上程安全的環境下使用.

            當定義一個Around 增強處理方法時,該方法的第一個形參必須是ProceedingJoinPoint 型別(至少包含一個形參〉, 在增強處理方法體內,呼叫ProceedingJoinPoint 的proceed()方法才會執行目標方法一一這就是Around 增強處理可以完全控制目標方法執行時機、如何執行的關鍵; 如果程式沒有呼叫ProceedingJoinPoint 的proceed()方法,則目標方法不會被執行。

            呼叫ProceedingJoinPoint 的proceed()方法時,還可以傳入一個Object[]物件,該陣列中的值將被傳入目標方法作為執行方法的實參。

            ProceedingJoinPoint 使用下面這些方法就可訪問到目標方法的相關資訊

            > Object[] getArgs(): 返回執行目標方法時的引數。

            > Signature getSignature(),返回被增強的方法的相關資訊。

            > Object getTarget(): 返回被織入增強處理的目標物件。

            > Object getTh is(), 返回AOP 框架為目標物件生成的代理物件。

 

    配置applicationContext.xml,自動掃描Bean元件類與切面類

<!-- 指定自動搜尋Bean元件,自動搜尋切面類 -->

<context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect">

    <context:include-filter type="annotation" expression 
      ="org.aspectj.lang.annotation.Aspect"/>

</context:component-scan>

<!-- 啟動@AspectJ 支援 -->

<aop : aspectj-autoproxy/>

   C.定義切入點:

   ---上面的每個增強註解都含有【execution(* org.crazyit.app.service.impl .*.*(..))"】完全可以提取出來,使用切入點代替。

   C1.定義切面內範圍的切入點

      當myPointcut()的修飾符為private時,則為切面範圍的切入點,

      引用方式:@AfterReturning(pointcut="myPointcut()”,returning="retVal")

   C2.定義可以共享的切入點

      當myPointcut()的修飾符為public時,則為可共享範圍的切入點,

      引用方式:

 

附:

關於面向切面程式設計的一些術語。

> 切面(Aspect) :業務流程執行的某個特定步驟,也就是應用執行過程的關注點, 關注點可能橫切多個物件,所以常常也稱為橫切關注點。

> 連線點( Joinpoint) : 程式執行過程中明確的點,如方法的呼叫,或者異常的丟擲。Spring AOP

中,連線點總是方法的呼叫,或者說僅支援將方法呼叫作為連線點。

> 增強處理(Advice ) : AOP 框架在特定的切入點執行的增強處理。處理有"around "," before "和“ after”等型別。

> 切入點( Pointcut) :可以插入增強處理的連線點。簡而言之, 當某個連線點滿足指定要求

時,該連線點將被新增增強處理,該連線點也就變成了切入點。

> 引入:將方法或欄位新增到被處理的類中。Spring 允許引入新的介面到任何被處理的物件。

例如,你可以使用一個引入,使任何物件實現lsModified 介面,以此來簡化快取。

> 目標物件:被AOP 框架進行增強處理的物件,也被稱為被增強的物件。如果AOP 框架是通

過執行時代理來實現的,那麼這個物件將是一個被代理的物件。

> AOP 代理: AOP 框架建立的物件,簡單地說,代理就是對目標物件的加強。Spring 中的AOP

代理可以是JDK 動態代理,也可以是CGL舊代理。前者為實現介面的目標物件的代理,後者為不實現介面的目標物件的代理。

> 織入( Weaving ) : 將增強處理新增到目標物件中,並建立一個被增強的物件( AOP 代理)

的過程就是織入。織入有兩種實現方式:編譯時增強(例如AspectJ )和執行時增強(例如

CGLIB ) 。Spring 和其他純JavaAOP 框架一樣,在執行時完成織入.