关于aspectj:Spring AOP围绕Abstract类的Abstract方法调用一些方法

Spring AOP invoking some methods around Abstract method of Abstract class

我有一个抽象类,比如

1
2
3
4
5
6
7
8
9
10
11
public abstract class EventHandler< T > {
  public < T > void preProcess(Message< T > message) {
    // do some pre-processing with the Message
  }

  protected abstract void handleEvent(Message< T > message) throws Exception;

  public < T > void postProcess(Message< T > message) {
    // do some post-processing with the Message
  }
}

有从这个类扩展的具体类。
当在具体类上调用 handleEvent 方法时,我希望能够使用 @Around 方面调用抽象类中的 preProcess() 和 postProcess() 方法。

我正在尝试定义如下方面

1
2
3
4
5
6
7
8
9
10
11
12
13
@Aspect
@Configuration
public class SomeAspect {

  @Around(value ="execution(* com.handler.EventHandler+.handleEvent(..)))")
  public void around(ProceedingJoinPoint proceedingJoinPoint) {
    1. invoke preProcess

    2. invoke the join point

    3. invoke postProcess
  }
}

我如何实现我想要的?

更新

1
2
3
4
5
6
7
8
9
10
@Aspect
@Component
public class SomeAspect {
  private Logger logger = LoggerFactory.getLogger(TenantAspect.class);

  @Around(value ="execution(* com.handler.EventHandler+.handleEvent(..))) && within(com.handler..*) && this(eventHandler) && args(message))")
  public void around(ProceedingJoinPoint proceedingJoinPoint, EventHandler<Object> eventHandler, Message<Object> message) {

  }
}

尝试了上述方法,编译器为 eventHandler 和 message

提供了 Unbound Pointcut Parameter


Following Aspect 也可以做到这一点。

解释

execution(* com.handler.EventHandler+.handleEvent(..)) - 执行名为 handleEvent 的方法,该方法属于 EventHandler

的子类型

指示符

within(com.handler..*) - 给定包

中建议类的作用域设计器

将参数传递给advice

this(eventHandler) - 执行方法的对象。 target() 也可以使用

args(message) - 在运行时传递的参数

笔记

一个方面最好用 @Component@Configuration 注释用于配置。

within 添加以缩小建议范围。请根据需要进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Aspect
@Component
public class EventHandlerAspect {

        @Around(value ="execution(* com.handler.EventHandler+.handleEvent(..))"
        +"&& within(com.handler..*)"
        +"&& this(eventHandler)"
        +"&& args(message))")
       public Object around(ProceedingJoinPoint proceedingJoinPoint,
        EventHandler<Object> eventHandler,
        Message<Object> message) throws Throwable {
            Object obj = null;
           // 1. invoke preProcess
            eventHandler.preProcess(message);
            try {
                // 2. invoke the join point
                obj = proceedingJoinPoint.proceed();
            } finally {
                // 3. invoke postProcess
                eventHandler.postProcess(message);
            }
            return obj;
         }
      }

希望这会有所帮助。


可以直接从progressingJoinPoint获取目标对象,如下:

1
2
3
((TestClass<Integer>) proceedingJoinPoint.getTarget()).preProcess(message);
 //or
((TestClass<Object>) proceedingJoinPoint.getTarget()).preProcess(message);

您需要知道泛型的实例化类型并拥有相同类型的匹配消息对象。

如果消息在被截获的函数调用的参数中,您可以按如下方式获取它们:

1
2
Object[] methodArguments = proceedingJoinPoint.getArgs();
Message<Integer> message = (Message<Integer>) methodArguments[0];

如果 message 是第一个参数,它将在 methodArguments[0]