@AspectJ中关于`advice`注解的使用

版权声明:仅供学习交流使用 https://blog.csdn.net/drxRose/article/details/84801102

使用@AspectJ,需要额外导入jar包,从官网下载即可,搜索关键字`aspectj download`.

说明,在有些参考书中,advice译为`增强`,依据其效用.

@Aspect 定义一个切面
@PointCut 定义复用指示器
@Before 前置通知
@After 后置通知

 @Around

环绕通知
@AfterReturning 返回通知
@AfterThrowing 异常通知

目标对象类

package siye;
import org.springframework.stereotype.Component;
@Component
public class TargetObj
{
	// 测试前置通知和后置通知
	public void work()
	{
		System.out.println("user_work");
	}
	// 测试异常通知.
	public void throwMethod()
	{
		throw new RuntimeException();
	}
	// 测试环绕通知.
	public void testAround()
	{
		System.out.println("test_around_advice");
	}
	// 测试返回通知,和参数截取.
	public int testReturn(int num)
	{
		return num;
	}
}

测试@AspectJ注解的切面类

package siye;
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.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component // 注册组件.
@Aspect // 切面,即切点和通知的组合.
public class AspectJtoAnno
{
	@Pointcut("execution(* *.work(..))") // 定义可重用的指示器.
	public void myPointCut()
	{
	}
	/*
	 * 前置通知和后置通知.
	 */
	@Before("myPointCut()")
	public void testAnnoBefore()
	{
		System.out.println("方法即将执行----advice_before");
	}
	@After("myPointCut()")
	public void testAnnoAfter()
	{
		System.out.println("方法执行完毕-----advice_after");
	}
	/*
	 * 环绕通知.
	 */
	@Around("execution(* *.testAround(..))")
	public void testAnnoAround(ProceedingJoinPoint jp)
	{
		// ProceedingJoinPoint,唯一作用,通知中,调用被通知的方法.
		// 不调用,该通知阻塞被通知方法的调用.
		try
		{
			System.out.println("方法开始执行----advice_around");
			jp.proceed();
			System.out.println("方法执行完毕----advice_around");
		} catch (Throwable e)
		{
		}
	}
	/*
	 * 异常通知.
	 */
	@AfterThrowing("execution(* *.throwMethod(..))")
	public void testAnnoAfterThrowing()
	{
		System.out.println("方法抛出异常----advice_throwing");
	}
	/*
	 * 返回通知和参数的获取.
	 */
	/**
	 * 提取方法中的参数.
	 * name binding only allowed in target, this, and args pcds
	 * 
	 * execution和args组合使用
	 */
	@AfterReturning("execution(* *.testReturn(int)) && args(num)")
	public void testAnnoAfterReturning(int num)
	{
		System.out.println("提取出来的参数值是" + num);
		System.out.println("方法正确执行已返回-----after_returning");
	}
}

上下文配置类

package siye;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class ConfigClass
{
}

测试注解类

package siye;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * advice使用的5个注解.
 * org.aspectj.lang.annotation.After;
 * org.aspectj.lang.annotation.AfterReturning;
 * org.aspectj.lang.annotation.AfterThrowing;
 * org.aspectj.lang.annotation.Around;
 * org.aspectj.lang.annotation.Before;
 * 
 * 切面使用的注解.
 * org.aspectj.lang.annotation.Aspect;
 */
public class UnitTest
{
	public static void main(String[] args)
	{
		String packName = UnitTest.class.getPackage().getName();// 反射获取包名称.
		AnnotationConfigApplicationContext context =
				new AnnotationConfigApplicationContext();
		context.register(ConfigClass.class);
		context.scan(packName);// 取代@ComponentScan.
		context.refresh();
		// System.out.println(context);
		TargetObj targetObj = context.getBean(TargetObj.class);
		targetObj.work();
		targetObj.testAround();
		targetObj.testReturn(12);
		try
		{
			System.out.println();
			targetObj.throwMethod();
		} catch (Exception e)
		{
		}
		context.close();
	}
}

猜你喜欢

转载自blog.csdn.net/drxRose/article/details/84801102