一,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共有兩種方式:
- 基於AspectJ的xml配置文件的方式
- 基於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配置文件中進行配置
在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">
配置兩個類對象
<!-- book對象 --> <bean id="book" class="cn.itcast.aop.Book"></bean> <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
配置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(* *.*(..))