自定义建议类
除了之前介绍的预定义建议类,你还可以实现自定义的建议类。虽然你可以提供任何 org.aopalliance.aop.Advice 的实现(通常是 org.aopalliance.intercept.MethodInterceptor),但我们通常建议你继承 o.s.i.handler.advice.AbstractRequestHandlerAdvice 类。这样做的好处是既能避免编写底层的面向切面编程代码,又能获得一个专门为此环境定制的开发起点。
子类需要实现 doInvoke() 方法,其定义如下:
/**
* Subclasses implement this method to apply behavior to the {@link MessageHandler} callback.execute()
* invokes the handler method and returns its result, or null).
* @param callback Subclasses invoke the execute() method on this interface to invoke the handler method.
* @param target The target handler.
* @param message The message that will be sent to the handler.
* @return the result after invoking the {@link MessageHandler}.
* @throws Exception
*/
protected abstract Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception;
回调参数是一种便捷方式,用于避免直接处理AOP的子类。调用 callback.execute() 方法会触发消息处理程序。
target 参数专为那些需要为特定处理器维护状态的子类而设计,通常通过以目标处理器为键的 Map 来保存状态。这一特性使得同一通知能够应用于多个处理器。RequestHandlerCircuitBreakerAdvice 正是利用此机制来为每个处理器维护断路器状态。
message 参数是发送给处理器的消息。虽然通知无法在调用处理器之前修改消息,但它可以修改消息负载(如果负载具有可变属性)。通常,通知会利用消息进行日志记录,或在调用处理器前后将消息副本发送到其他位置。
通常,返回值会是 callback.execute() 返回的值。然而,通知确实有能力修改返回值。请注意,只有 AbstractReplyProducingMessageHandler 实例会返回值。以下示例展示了一个扩展 AbstractRequestHandlerAdvice 的自定义通知类:
public class MyAdvice extends AbstractRequestHandlerAdvice {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
// add code before the invocation
Object result = callback.execute();
// add code after the invocation
return result;
}
}
除了 execute() 方法外,ExecutionCallback 还提供了一个额外的方法:cloneAndExecute()。在某些情况下必须使用此方法,例如在 doInvoke() 的单次执行中可能多次调用该调用时,比如在 RequestHandlerRetryAdvice 中。这是必需的,因为 Spring AOP 的 org.springframework.aop.framework.ReflectiveMethodInvocation 对象通过跟踪链中最后调用的通知来维护状态。每次调用时都必须重置此状态。
更多信息,请参阅 ReflectiveMethodInvocation Javadoc。