检查Spring AOP中的方法是否被另一个带注释的方法调用



我在我的Spring启动项目方面使用,它在注释类中的每个公共方法上触发:

@Aspect
@Component
public class DeletedAwareAspect {
@Before("@within(com.example.DeleteAware)")
public void aroundExecution(JoinPoint pjp) throws Throwable {
//... some logic before
}
@After("@within(com.example.DeleteAware)")
public void cleanUp(JoinPoint pjp) throws Throwable {
//... some logic after
}
}

该方面的用法如下:

@DeleteAware
@Service
public class MyService {
public void foo() {}
}
@DeleteAware
@Service
public class MyAnotherService {
@Autowired
private MyService service;
public void anotherFoo() {}
public void VERY_IMPORTANT_METHOD() {
service.foo();
}
}

MyService.foo()和MyAnotherService.anotherFoo()按预期工作。但这里有一个问题-如果方法包装的方面是由另一个方面的方法(如VERY_IMPORTANT_METHOD())调用,我不想点燃方面两次,但只有一次。如何从方面检查方法是否在另一个方面的方法内调用?

就像我说的,如果你想切换到本地AspectJ,你可以使用percflow()方面实例化和/或cflow()切入点,但我不会在这里详细解释,因为你正在寻找一个Spring AOP解决方案。就像R.G说的,它实际上很简单:为方面嵌套级别使用线程本地计数器,并且仅在计数器为零时才执行一些操作(例如在after通知中删除某些内容)。

@Aspect
@Component
public class DeletedAwareAspect {
private ThreadLocal<Integer> nestingLevel = ThreadLocal.withInitial(() -> 0);
@Before("@within(com.example.DeleteAware)")
public void aroundExecution(JoinPoint pjp) {
int level = nestingLevel.get() + 1;
nestingLevel.set(level);
System.out.println("BEFORE " + pjp + " -> " + level);
}
@After("@within(com.example.DeleteAware)")
public void cleanUp(JoinPoint pjp) {
int level = nestingLevel.get() - 1;
nestingLevel.set(level);
System.out.println("AFTER " + pjp + " -> " + level);
if (level == 0)
System.out.println("Deleting something");
}
}

相关内容

  • 没有找到相关文章

最新更新