我有一个父类和一个子类。父类有一个变量a,子类有一个变量b。当我对父类/子类执行geta时,我的调用将转到around方面。我想要的是,当我调用geta或子类上的任何子类方法时,调用应该只转到around。我打电话给家长的时候不应该到处乱跑。
9lowa7mx1#
如果您想避免显式地命名方面中的所有子类或显式地注解所有子类(这既会产生维护工作,也可能会被遗忘),您可以在advice方法的开头检查springbean的运行时类型,并跳过所有特殊处理,如日志记录、分配默认返回值等。基类和 Employee 它的子类是spring aop的目标,也就是说,它们是spring代理,在获得真正的目标类类型之前,必须先将它们展开。这通常是通过 AopTestUtils.getTargetObject(mySpringComponent) .我简化了您的方面代码,以便关注主要问题:
Employee
AopTestUtils.getTargetObject(mySpringComponent)
package com.journaldev.spring.aspect; import com.journaldev.spring.model.Employee; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import org.springframework.test.util.AopTestUtils; @Component @Aspect public class EmployeeAroundAspect { @Around("execution(* get*(..)) && this(employee)") public Object employeeAroundAdvice(ProceedingJoinPoint proceedingJoinPoint, Employee employee) throws Throwable { // Skip logging for base class 'this' if (AopTestUtils.getTargetObject(employee).getClass().equals(Employee.class)) return proceedingJoinPoint.proceed(); System.out.println(proceedingJoinPoint); Object value = proceedingJoinPoint.proceed(); System.out.println(" Return value = " + value); return value; } }
p、 s:如果您只想记录结果,则 @AfterReturning 建议可能更容易,因为您不必继续或处理/抛出异常。但这超出了你的问题范围。fwiw,建议如下:
@AfterReturning
@AfterReturning(pointcut = "execution(* get*(..)) && this(employee)", returning = "returnValue") public void employeeAfterReturningAdvice(JoinPoint joinPoint, Employee employee, Object returnValue) { // Skip logging for base class 'this' if (AopTestUtils.getTargetObject(employee).getClass().equals(Employee.class)) return; System.out.println(joinPoint); System.out.println(" Return value = " + returnValue); }
tez616oj2#
使用这样的切入点定义,geta的两个方法都将在父级和子级中进行切入,这就是它应该工作的。因此,如果您只想在子geta上进行剪切,那么需要提供一些有关剪切定义的其他信息。例如添加注解
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation {}
然后只给孩子注解,
@MyAnnotation public class Child extends Parent{}
并将方面定义为
@Around( "execution(* dummy.test.SubClass.get*(..)) && @this(dummy.test.MyAnnotation)" )
那么只有子类中的geta将被aspected
2条答案
按热度按时间9lowa7mx1#
如果您想避免显式地命名方面中的所有子类或显式地注解所有子类(这既会产生维护工作,也可能会被遗忘),您可以在advice方法的开头检查springbean的运行时类型,并跳过所有特殊处理,如日志记录、分配默认返回值等。
基类和
Employee
它的子类是spring aop的目标,也就是说,它们是spring代理,在获得真正的目标类类型之前,必须先将它们展开。这通常是通过AopTestUtils.getTargetObject(mySpringComponent)
.我简化了您的方面代码,以便关注主要问题:
p、 s:如果您只想记录结果,则
@AfterReturning
建议可能更容易,因为您不必继续或处理/抛出异常。但这超出了你的问题范围。fwiw,建议如下:tez616oj2#
使用这样的切入点定义,geta的两个方法都将在父级和子级中进行切入,这就是它应该工作的。因此,如果您只想在子geta上进行剪切,那么需要提供一些有关剪切定义的其他信息。
例如添加注解
然后只给孩子注解,
并将方面定义为
那么只有子类中的geta将被aspected