1. 程式人生 > >Spring入門學習(AOP前置通知和後置通知) 第十五節

Spring入門學習(AOP前置通知和後置通知) 第十五節

Spring入門學習(AOP前置通知)

AOP前置通知

前置通知:在方法之前執行的通知,使用`@Before`註解並將切入點表示式的值作為註解值。
  1. 使用Maven新增依賴的jar包:
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <
    artifactId
    >
    spring-context</artifactId> <version>4.1.2.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</
    artifactId
    >
    <version>4.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.1.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
    <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.1.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.8</version> </dependency>
  2. 繼續使用上節中的ArithmeticCalculatorArithmeticCalculatorImpl類。
  3. 新建一個LoggingAspect切面類:
    其中@Component註解標註為一個被Spring管理的bean,@Aspect將類標註為切面類;execution(* com.fafa.spring.aop.impl.*.*(..))execution(public int com.fafa.spring.aop.impl.ArithmeticCalculator.add(int, int))的抽象精簡寫法,第一個*代表匹配任意修飾符及任意返回值,第二個*表示com.fafa.spring.aop.impl包中的任意類,第三個*表示類中的任意方法,括號中的..表示方法的任意引數。
    // 把這個類宣告為一個切面: 需要把該類放入到IOC容器中,再宣告為一個切面
    @Component
    @Aspect
    public class LoggingAspect {
    
    	// 宣告該方法是一個前置通知:在目標方法開始之前執行
    //	@Before("execution(public int com.fafa.spring.aop.impl.ArithmeticCalculator.add(int, int))")
    	@Before("execution(* com.fafa.spring.aop.impl.*.*(..))")
    	public void beforeMethod(JoinPoint joinPoint) {
    		String methodName = joinPoint.getSignature().getName();
    		List<Object> args = Arrays.asList(joinPoint.getArgs());
    		System.out.println("The method" + methodName +" begins..." + args);
    	}
    }
    
    JoinPoint引數表示連線點,可以獲取到方法名和引數。
  4. 建立一個Spring配置檔案applicationContext.xml
    使用@AspectJ註解會自動為匹配的類生成代理物件:<aop:aspectj-autoproxy></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:context="http://www.springframework.org/schema/context"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.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.1.xsd">
    
    	<!-- 配置自動掃描的包 -->
    	<context:component-scan base-package="com.fafa.spring.aop.impl"></context:component-scan>
    	
    	<!-- 使AspectJ註解起作用 :自動為匹配的類生成代理物件-->
    	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    	
    </beans>
    
  5. 建立測試類:
    public class Main {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
    		
    		ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
    		
    		int result = arithmeticCalculator.add(3, 6);
    		System.out.println("result:" + result);
    	
    		result = arithmeticCalculator.div(6, 3);
    		System.out.println("result:" + result);
    	}
    }
    
    測試結果:在方法返回值前都添加了相應的資訊
    The methodadd begins...[3, 6]
    result:9
    The methoddiv begins...[6, 3]
    result:2
    

後置通知

  1. 使用@After註解標註,在LoggingAspect類中新增如下方法:
    // 後置通知就是在目標方法執行後(無論是否發生異常),都會執行的通知
    // 在後置通知中還不能訪問目標方法執行的結果。
    @After("execution(* com.fafa.spring.aop.impl.*.*(..))")
    public void afterMethod(JoinPoint joinPoint) {
    	String methodName = joinPoint.getSignature().getName();
    	System.out.println("The method "+methodName+" ends...");
    }
    
  2. 執行結果:
    The methodadd begins...[3, 6]
    The method add ends...
    result:9
    The methoddiv begins...[6, 3]
    The method div ends...
    result:2
    
    afterMethod方法結束,此時還無法在結束時獲取到返回的結果,後面可以使用返回通知獲取到返回值。