1. 程式人生 > >基於註解的AOP配置

基於註解的AOP配置

基於 錯誤 出現 參數 href ... 執行順序 nco 1.0

配置文件

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配置