Spring框架(三)——AOP
目錄
一、AOP概述
AOP(Aspect Oriented Programming):面向切面程式設計;將程式重複的程式碼抽取出來,執行時,使用動態代理的技術,在不修改原始碼的基礎上,對已有方法進行增強。
相關術語
名稱 | 功能 |
---|---|
連線點(Joint Point) | 連線點是指那些被攔截的方法 |
切入點(Pointcut) | 切入點是指對Jointpoint進行攔截的定義 |
通知(Advice) | 通知是指攔截到Joinpoint之後所要做的事情 |
目標物件(Target) | 被代理的物件 |
代理(Proxy) | 增強後的物件 |
切面(Aspect) | 切入點和通知的結合 |
二、整合AOP
2.1 匯入jar包
匯入aop相關的jar包:
aopalliance-1.0.jar
aspectjweaver-1.9.4.jar
spring-aop-5.1.9.RELEASE.jar
spring-aspects-5.1.9.RELEASE.jar
或者使用maven匯入依賴包
<!--spring-aop-->
<dependency >
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.9.RELEASE</version>
</dependency>
<!--spring-aspects-->
<dependency>
<groupId>org.springframework</groupId>
< artifactId>spring-aspects</artifactId>
<version>5.0.9.RELEASE</version>
</dependency>
<!--aopalliance-->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- aspectjweaver-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
Spring4之後和2.5發生了很大的變化,原來的spring2.5很多倚賴的jar包都是隨著spring一起釋出的,現在spring4之後的版本已經不再發布倚賴包,需要自己匯入;
2.2 開啟支援
在配置檔案中開啟aop的支援;
<aop:aspectj-autoproxy/>
2.3 定義切面類
建立切面類,並設定通知方法
@Component
@Aspect
public class UserLog {
@Before("execution(* com.spring.bean.UserBean.work(..))")
public void Before(){
System.out.println("前置通知...");
}
}
2.4 測試
public class userTest {
@Test
public void test(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("SpringConfig.xml");
UserBean userBean = (UserBean) ac.getBean("userBean");
userBean.work();
}
}
執行結果:
三、使用註解
3.1 常用註解
-
@Aspect 把當前類宣告為切面
-
@Before(value=“切入表示式”) 把當前方法設定為前置通知
-
@AfterReturning(value=“切入表示式”) 把當前方法設定為後置通知
-
@After(value=“切入表示式”) 把當前方法設定為最終通知
-
@AfterThrowing(value=“切入表示式”) 把當前方法設定為異常通知
-
@Around 把當前方法設定為環繞通知,即@Before和@After的結合
-
@Pointcut(value=“切入表示式”) 指定切入表示式
3.2 @AfterReturning和@After的區別
1)它們都是在切入方法執行完成後執行,但是@AfterReturning在@After之後執行;
2)如果方法出現異常,那麼@AfterReturning將不會執行;而@After無論方法是否正常結束,它都會被執行;
3)@AfterReturning可以訪問目標方法的返回值,而@After就無法做到;
@AfterReturning(value="execution(* com.xjy.service.impl.*.*(..))", returning="rt")
public void afterReturn(Object rt) throws Throwable {
System.out.println("切入方法的返回值:" + rt);
System.out.println("方法返回通知...");
}
注意:returning屬性值要與方法的引數名相同。
3.3 切入表示式
切入點表示式語法:
//1、攔截所有public方法
execution(public * *(..))
//2、攔截所有save開頭的方法
execution(* add*(..))"
//3、攔截指定類的指定方法, 攔截時候一定要定位到方法
execution(* com.tung.dao.UserDao.add(..))
//4、攔截指定類的所有方法
execution(* com.tung.dao.UserDao.*(..))
//5、攔截指定包,以及其自包下所有類的所有方法
execution(* com..*.*(..))
//6、多條件
// 或:|| or
execution(* com.tung.dao.UserDao.add(..)) || execution(* com.tung.dao.AccountDao.add(..))
execution(* com.tung.dao.UserDao.add(..)) or execution(* com.tung.dao.AccountDao.add(..))
//且:&& and
execution(* com.tung.dao.UserDao.add(..)) && execution(* com.tung.dao.AccountDao.add(..)
execution(* com.tung.dao.UserDao.add(..)) and execution(* com.tung.dao.AccountDao.add(..)
//7、取非值:! not
!execution(* com.tung.dao.UserDao.add(..))"
//注意not前必須有空格
not execution(* com.tung.dao.UserDao.add(..))"
四、零配置(無配置檔案)
- 建立配置類
- 使用@Configuration註解,指定Spring容器從當前類中載入讀取配置資訊即可實現零配置;
- 使用@ComponentScan註解,指定spring容器初始化時候要掃描的包;
- 使用@EnableAspectJAutoProxy註解,啟用aop功能。
@Configuration
@ComponentScan(basePackages = {"com.spring"})
// 啟用aop功能
@EnableAspectJAutoProxy
public class SpringConfig {
}