Spring_使用注解創建切面


讀萬卷書,行萬里路。

定義切面

  在使用AspectJ注解定義切面時,需要引入aspectjrt.jar 和 aspectjweaver.jar

  1.使用@Aspect注解標注類為切面。

  2.使用以下AspectJ注解來聲明切面通知方法:

    1)@After:通知方法在目標方法返回或拋出異常后調用;

    2)@AfterReturning:通知方法在目標方法返回后調用;

    3)@AfterThrowing:通知方法在目標方法拋出異常后調用;

    4)@Around:通知方法將目標方法封裝起來;

    5)@Before:通知方法在目標方法調用之前執行。

  如下,使用AspectJ注解將普通的POJO類標注為切面:

package chapter4.practice1;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
 * POJO
 * 使用@Aspect標注該POJO也是切面
 */
@Aspect
public class Audience {
    /**
     * 在chapter4.practice1.Performance類的perform方法調用前執行
     */
    @Before("execution(** chapter4.practice1.Performance.perform(..))")
    public void drink() {
        System.out.println("Drink water...");
    }
    
    /**
     * 在chapter4.practice1.Performance類的perform方法返回后執行
     */
    @AfterReturning("execution(** chapter4.practice1.Performance.perform(..))")
    public void eat() {
        System.out.println("Eat food...");
    }
    
    /**
     * 在chapter4.practice1.Performance類的perform方法拋出異常后執行
     */
    @AfterThrowing("execution(** chapter4.practice1.Performance.perform(..))")
    public void refund() {
        System.out.println("Demand refund...");
    }
    
}

  

  在上述代碼中可發現相同的切點表達式重復定義了三次,我們可以使用@Pointcut注解在@AspectJ切面定義可重復使用的切點。

package chapter4.practice1;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
 * POJO
 * 使用@Aspect標注該POJO也是切面
 */
@Aspect
public class Audience {
    /**
     * 使用@Pointcut設置切點表達式
     */
    @Pointcut("execution(** chapter4.practice1.Performance.perform(..))")
    public void performance() {}
    
    /**
     * 在chapter4.practice1.Performance類的perform方法調用前執行
     */
    @Before("performance()")
    public void drink() {
        System.out.println("Drink water...");
    }
    
    /**
     * 在chapter4.practice1.Performance類的perform方法返回后執行
     */
    @AfterReturning("performance()")
    public void eat() {
        System.out.println("Eat food...");
    }
    
    /**
     * 在chapter4.practice1.Performance類的perform方法拋出異常后執行
     */
    @AfterThrowing("performance()")
    public void refund() {
        System.out.println("Demand refund...");
    }
    
}

 

啟用自動代理

  以上代碼創建了一個簡單切面,我們還需啟用自動代理,這樣@Aspect標注的類才會被視為切面,這些注解才會被解析。啟用自動代理的方式以下兩種:

  1.在Java配置類JavaConfig使用@EnableAspectJAutoProxy注解啟用自動代理功能。

package chapter4.practice1;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class JavaConfig {
    
    @Bean
    public Audience audience() {
        return new Audience();
    }
}

 

  2.在XML配置中使用Spring AOP命名空間中的<aop:aspectj-autoproxy>元素啟用自動代理功能。

<?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:c="http://www.springframework.org/schema/c"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc 
http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"
> <context:component-scan base-package="chapter4.practice1" /> <aop:aspectj-autoproxy/> <bean id="audience" class="chapter4.practice1.Audience"></bean> </beans>

 

  Spring的AspectJ自動代理僅使用@AspectJ作為創建切面的指導,切面依然是基於代理的。如果想利用AspectJ的所有功能,必須在運行時使用AspectJ並且不依賴Spring來創建基於代理的切面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM