SpringMvc之AspectJ(二)

doublespring注解

使用 aspectj 处理拦截aop,需要获取实现类接口上的注解。

Aspectj 使用 org.aspectj.lang.JoinPoint 接口表示目标类拦截点对象,如果是环绕增强时,使用 org.aspectj.lang.ProceedingJoinPoint 表示连接点对象,该类是 JoinPoint 的子接口。如何一个增强反腐都可以通过将第一个入参声明为 JoinPoint 访问到连接点上下文的信息

两个接口的主要方法:

JoinPoint

JoinPoint 对象封装了 SpringAop 中切面方法的信息,在切面方法中添加 JoinPoint 参数,就可以获取到封装了该方法信息的 JoinPoint 对象。

public interface JoinPoints { /** * 连接点所在位置的全部相关信息 * @return execution(public java.lang.String com.isyxf.myaop.controller.v1.MyTest.say()) */ String toLongString(); /** * 连接点所在位置的相关信息 * @return execution(String com.isyxf.myaop.controller.v1.MyTest.say()) */ @Override String toString(); /** * 连接点所在位置的简单相关信息 * @return execution(MyTest.say() */ String toShortString(); /** * 连接点类型 * @return */ String getKind(); /** * 获取代理对象 * @return */ Object getThis(); /** * 获取被代理的对象 * @return */ Object getTarget(); /** * 获取传入目标方法的参数对象 * @return */ Object[] getArgs(); /** * 获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息 * @return */ Signature getSignature(); /** * 返回连接点方法所在类文件中的位置 * @return */ SourceLocation getSourceLocation(); /** * 返回连接点静态部分 * @return */ JoinPoint.StaticPart getStaticPart(); }

ProceedingJoinPoint

该对象只用在 @Around 的切面方法中,ProceedingJoinPoint 继承了 JoinPoint,是在 JoinPoint 的基础上暴露出 proceed, 如果不调用 ProceedingJoinPoint的 proceed 方法,那么目标方法就被拦截了。

@RestController public class MyTest { @GetMapping("/api/say") public String say(@RequestParam("foo") String foo) { return "test"; } }
@Component @Aspect public class LogAspectJ { @Pointcut("execution(* com.isyxf.myaop.controller.v1.MyTest.say(..))") private void say() {} @Around("execution(* com.isyxf.myaop.controller.v1.MyTest.say(..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕前通知======="); // 执行目标方法,并得到返回值,如果不调用该方法则是阻止目标方法执行 Object obj = joinPoint.proceed(); // 环绕后通知 System.out.println("环绕后通知========="); return obj.toString() + ", 环绕后通知增强"; } }