基於註解的AOP配置
配置文件
spring配置文件中的約束
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:context="http://www.springframework.org/schema/context"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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
在spring配置文件中配置Spring創建容器時要掃描的包
<context:component-scan base-package="com.itheima"></context:component-scan>
在spring配置文件中開啟spring對註解AOP的支持
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
在pom.xml中添加依賴
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency>
若不使用配置文件而使用配置類配置Spring
使用配置類而不使用XML文件(代替bean.xml)對spring進行配置
@Configuration //指定當前類是一個spring配置類 @ComponentScan(basePackages="com.itheima") // 配置spring創建容器時要掃描的包 @EnableAspectJAutoProxy //配置spring開啟註解AOP的支持 public class SpringConfiguration { }
註解配置
把資源使用註解配置
把通知類也使用註解配置
在通知類上使用@Aspect註解聲明為切面
在增強的方法上使用註解配置通知
@Before
作用: 把當前方法看成是前置通知。
屬性: value:用於指定切入點表達式,還可以指定切入點表達式的引用。
//開啟事務
@Before("execution(* com.itheima.service.impl.*.*(..))") public void beginTransaction() { try { dbAssit.getCurrentConnection().setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } }
@AfterReturning
作用: 把當前方法看成是後置通知。
屬性: value:用於指定切入點表達式,還可以指定切入點表達式的引用
@AfterThrowing
作用: 把當前方法看成是異常通知。
屬性: value:用於指定切入點表達式,還可以指定切入點表達式的引用
@After
作用: 把當前方法看成是最終通知。
屬性: value:用於指定切入點表達式,還可以指定切入點表達式的引用
環繞通知註解配置
@Around
作用: 把當前方法看成是環繞通知。
屬性: value:用於指定切入點表達式,還可以指定切入點表達式的引用。
未使用切入點表達式註解, 直接在@Around中指定切入點表達式
/** * 環繞通知 * @param pjp * @return */ @Around("execution(* com.itheima.service.impl.*.*(..))") public Object transactionAround(ProceedingJoinPoint pjp) { //定義返回值 Object rtValue = null; try { //獲取方法執行所需的參數 Object[] args = pjp.getArgs(); //前置通知:開啟事務 beginTransaction(); //執行方法 rtValue = pjp.proceed(args); //後置通知:提交事務 commit(); }catch(Throwable e) { //異常通知:回滾事務 rollback(); e.printStackTrace(); }finally { //最終通知:釋放資源 release(); } return rtValue; }
使用切入點表達式註解, 在@Around中指定切入點表達式引用
@Pointcut
作用: 指定切入點表達式
屬性:value:指定表達式的內容
使用時
@Around("pt1()") 千萬別忘了寫括號
@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
private void pt1() {}
@Around("pt1()")//註意:千萬別忘了寫括號
public Object transactionAround(ProceedingJoinPoint pjp) {
......
.....
}
註意:
在使用除環繞通知的其他通知時,他們的順序並不是一定的,最終通知會執行優先於後置通知與環繞通知,
因此當我們使用最終通知來釋放一些資源的時候,可能會出現資源已經釋放,但是後置通知仍在使用的情況,這時就會出現錯誤,
因此我們遇到這種情況時要特別註意,為了保證通知的順序,我們必要的使用環繞通知,環繞通知的執行順序是一致的。
基於註解的AOP配置