2-6 Spring基於AspectJ的AOP開發:XML的方式

一,AspectJ的概述:

    1,AspectJ是一個面向切面的框架,它擴展了Java語言

    2,AspectJ定義了AOP語法所以它有一個專門的編譯器用來生成遵守Java字節編碼規範的Class文件。

    3,AspectJ是一個基於Java語言的AOP框架。

    4,Spring2.0以後新增了對AspectJ切點表達式的支持

    5,@AspectJ是AspectJ1.5新增的功能,通過JDK5註解技術,允許直接在Bean類中定義切面。

    6,新版本Spring框架,建議使用AspectJ方式來開發AOP,使用AspectJ需要導入Spring AOP和AspectJ相關的Jar包。 

    7,AspectJ並不是Spring框架的一部分,而是一個單獨的面向切面的框架,只不過它經常和Spring框架一起使用進行AOP的操作而已。


二,使用AspectJ方式來開發AOP共有兩種方式:

  1. 基於AspectJ的xml配置文件的方式
  2. 基於AspectJ的註解的方式


三,Spring使用AspectJ進行AOP的開發:XML的方式

第一步,引入相應的Jar包 
上面我說過,除了導入最基本的Jar包外,使用AspectJ還需要導入Spring AOP和AspectJ相關的Jar包。

  • Spring的傳統AOP的開發的包: 
    • spring-aop-4.2.4.RELEASE.jar
    • aopalliance-1.0.jar
  • AspectJ的開發包 
    • aspectjweaver-1.8.7.jar
    • spring-aspects-4.2.4.RELEASE.jar

第二步,編寫目標類 
在src目錄下創建一個cn.itcast.aop包,並在該包下編寫一個目標類。

public class Book {

    public void add() {
        System.out.println("book add.................");
    }

}

第三步,創建增強的類以及增強的方法

public class MyBook {

    // 前置通知
    public void before1() {
        System.out.println("before........");
    }

}

我們現在要求在Book類裏面的add方法之前執行MyBook類裏面的before1的方法。 
第四步,在Spring配置文件中進行配置

  1. 在Spring配置文件中引入aop約束

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop.xsd">

  2. 配置兩個類對象

    <!-- book對象 -->
    <bean id="book" class="cn.itcast.aop.Book"></bean>
    <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>

  3. 配置AOP操作,即需要配置切入點和切面。

    <!-- 配置AOP的操作  -->
    <aop:config>
        <!-- 配置切入點,對Book類裏面的所有方法都增強 -->
        <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut>
    
        <!-- 配置切面    aop:aspect標籤裏面使用屬性ref,ref屬性值寫增強類的bean的id值 -->
        <aop:aspect ref="myBook">
            <!-- 
                增強類型
                method屬性:增強類的方法名稱
                pointcut-ref屬性:切入點的id值
            -->
            <!-- 前置通知 -->
            <aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
        </aop:aspect>
    </aop:config>

第五步,編寫一個單元測試類並進行測試 
在cn.itcast.aop包下編寫一個TestDemo單元測試類。

public class TestDemo {

    @Test
    public void testUser() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book = (Book) context.getBean("book");
        book.add();
    }
}

其實我們也可以整合Junit單元測試,Spring對Junit4進行了支持,可以通過註解方便的測試Spring程序,所以就不必寫那麼麻煩的單元測試類了。首先導入如下Jar包: 
這裏寫圖片描述 
然後編寫如下的單元測試類:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/bean2.xml") // 或者也可寫爲:@ContextConfiguration("classpath:bean2.xml")
public class TestDemo {

    @Autowired
    private Book book;

    @Test
    public void demo1() {
        book.add();
    }

}

演示其他通知類型

先將MyBook增強類的代碼修改爲:

public class MyBook {

    // 前置通知
    public void before1() {
        System.out.println("before........");
    }

    // 後置通知
    public void after11() {
        System.out.println("after...........");
    }

    // 環繞通知
    public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法之前執行...........");
        // 讓被增強的方法執行
        joinPoint.proceed();
        System.out.println("方法之後執行...........");
    }

}

然後再在Spring配置文件中進行配置。

<!-- 配置AOP的操作  -->
<aop:config>
    <!-- 配置切入點,對Book類裏面的所有方法都增強 -->
    <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"></aop:pointcut>

    <!-- 配置切面    aop:aspect標籤裏面使用屬性ref,ref屬性值寫增強類的bean的id值 -->
    <aop:aspect ref="myBook">
        <!-- 
            增強類型
            method屬性:增強類的方法名稱
            pointcut-ref屬性:切入點的id值
        -->
        <!-- 前置通知 -->
        <aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
        <!-- 後置通知 -->
        <aop:after-returning method="after11" pointcut-ref="pointcut1"></aop:after-returning>
        <!-- 環繞通知 -->
        <aop:around method="around1" pointcut-ref="pointcut1"></aop:around>
    </aop:aspect>
</aop:config>

切入點表達式

通過execution函數,可以定義切點的方法切入。 
語法爲:execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)。 
例如:

  • 匹配所有類的public方法:execution(public *.*(..))
  • 匹配指定包下所有類的方法:execution(* cn.itcast.dao.*(..)),但不包含子包
  • execution(* cn.itcast.dao..*(..))..*表示包、子孫包下所有類。
  • 匹配指定類所有方法:execution(* cn.itcast.service.UserService.*(..))
  • 匹配實現特定接口的所有類的方法:execution(* cn.itcast.dao.GenericDAO+.*(..))
  • 匹配所有save開頭的方法:execution(* save*(..))
  • 匹配所有類裏面的所有的方法:execution(* *.*(..))

發佈了45 篇原創文章 · 獲贊 31 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章