介绍spring AOP前置通知、后置通知、返回通知、异常通知、环绕通知

依赖:

1.aspectjrt

2.aspectjweaver


详细:

pom.xml 增加配置:

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.6.RELEASE</version>
    </dependency>
    <dependency>
	    <groupId>org.aspectj</groupId>
	    <artifactId>aspectjrt</artifactId>
	    <version>1.8.9</version>
	</dependency>
	<dependency>  
	    <groupId>org.aspectj</groupId>  
	    <artifactId>aspectjweaver</artifactId>  
	    <version>1.8.9</version>  
   	 <scope>runtime</scope>  
	</dependency>  
  </dependencies>


ArithmeticCalculator.java

package com.shuoeasy.test;

/**
 * 定义计算器接口
 *
 */
public interface ArithmeticCalculator {
	double add(double num1, double num2);
	double sub(double num1, double num2);
	double mul(double num1, double num2);
	double div(int num1, int num2);
}

ArithmeticCalculatorImpl.java:

package com.shuoeasy.test;

import org.springframework.stereotype.Component;

/**
 * 业务类
 */
@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator{

	public double add(double num1, double num2) {
		double result = num1 + num2;
		return result;
	}

	public double sub(double num1, double num2) {
		double result = num1 - num2;
		return result;
	}

	public double mul(double num1, double num2) {
		double result = num1 * num2;
		return result;
	}

	public double div(int num1, int num2) {
		double result = num1 / num2;
		return result;
	}
}

LogAspect.java

package com.shuoeasy.test;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

// 声明为一个切面:需要把该类放入IOC容器中、再声明为一个切面
@Aspect
@Component
public class LogAspect {
	public static final String EDP = "execution(public double com.shuoeasy.test.ArithmeticCalculator.add(double, double))";
	
	// 前置通知。声明该方法是一个前置通知:在目标方法之前执行
	@Before(EDP)
	public void beforeMethod(JoinPoint joinPoint){
		String methodName = joinPoint.getSignature().getName();
		Object[] args = joinPoint.getArgs();
		System.out.println("The method " + methodName + " @Before, args:" + Arrays.asList(args));
	}
	
	// 后置通知。目标方法执行之后执行,无论该方法是否出现异常
	@After("execution(* com.shuoeasy.test.*.*(..))")
	public void afterMethod(JoinPoint joinPoint){
		String methodName = joinPoint.getSignature().getName();
		Object[] args = joinPoint.getArgs();
		System.out.println("The method " + methodName + " @After, args:" + Arrays.asList(args));
	}
	
	// 返回通知。在方法正常执行后,返回通知是可以访问该方法返回值的
	@AfterReturning(value="execution(* com.shuoeasy.test.*.*(..))",returning="result")
	public void afterReturning(JoinPoint joinPoint, Object result){
		String methodName = joinPoint.getSignature().getName();
		Object[] args = joinPoint.getArgs();
		System.out.println("The method " + methodName + " @AfterReturning, return:" + result);
	}
	
	// 异常通知。在目标方法出现异常时执行代码,可以访问到异常对象,且可以指定出现特定异常时执行通知代码
	@AfterThrowing(value="execution(* com.shuoeasy.test.*.*(..))",throwing="ex")
	public void afterThrowing(JoinPoint joinPoint, Exception ex){
		// 也可以将Exception改为特定的异常类型NullPointerException ex
		String methodName = joinPoint.getSignature().getName();
		System.out.println("The method " + methodName + " @AfterThrowing, ex:" + ex.toString());
	}
	
	// 环绕通知。需要携带ProceedingJoinPoint类型的参数。
	// 类似动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
	// 且环绕通知有返回值,返回值即目标方法的返回值
	@Around("execution(* com.shuoeasy.test.*.*(..))")
	public Object aroundMethod(ProceedingJoinPoint pjd){
		
		//return 100.0; // 如果return 100.0,目标方法的返回值就被强制改为100.0
		
		Object result = null;
		String methodName = pjd.getSignature().getName();
		Object[] args = pjd.getArgs();
		
		try {
			// 前置通知
			System.out.println("The method " + methodName + " @Around->Before, args:" + Arrays.asList(args));
			// 执行目标方法
			result = pjd.proceed();
			// 后置通知
			System.out.println("The method " + methodName + " @Around->AfterReturning, return:" + result);
		} catch (Throwable e) {
			// 异常通知
			System.out.println("The method " + methodName + " @Around->AfterThrowing, e:" + e.toString());
			throw new RuntimeException(e);
		}
		// 后置通知
		System.out.println("The method " + methodName + " @After, args:" + Arrays.asList(args));
		
		return result;
	}
}

bean.xml

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="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.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
	
	<!-- 自动扫描的包 -->
	<context:component-scan base-package="com.shuoeasy.test"></context:component-scan>
	
	<!-- 使用Aspjectj 注解起作用:自动为匹配的类生成代理对象 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Main.java

package com.shuoeasy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		// 1.创建spring的IOC容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
		// 2.从IOC容器中获取bean的实例
		ArithmeticCalculator arithmeticCalulator = (ArithmeticCalculator)ctx.getBean("arithmeticCalculator");

		// 3.使用bean
		double result = arithmeticCalulator.add(2, 3);
		System.out.println("result=" + result);
	}
}

输出:

The method add @Around->Before, args:[2.0, 3.0]

The method add @Before, args:[2.0, 3.0]

The method add @Around->AfterReturning, return:5.0

The method add @After, args:[2.0, 3.0]

The method add @After, args:[2.0, 3.0]

The method add @AfterReturning, return:5.0

result=5.0


你可能感兴趣的文章