是否可以在不使用AspectJ的情况下拦截使用@RabbitListener注释的bean方法的调用。
代码是这样的
@OtherAnnotation
@RabbitListener
public void do(Message message)
如果方法有@OtherAnnotation注释,我需要拦截对@RabbitListener方法的所有调用。
更新
我设法使用Gary Russell解决方案。
public class CustomRabbitListenerAnnotationBeanPostProcessor extends RabbitListenerAnnotationBeanPostProcessor {
@Override
protected void processAmqpListener(RabbitListener rabbitListener, final Method method, Object bean, String beanName) {
if (method.isAnnotationPresent(OtherAnnotation.class)) {
ProxyFactory proxyFactory = new ProxyFactory(bean);
proxyFactory.addAdvisor(new StaticMethodMatcherPointcutAdvisor(new OtherAnnotationInterceptor()) {
@Override
public boolean matches(Method advisorMethod, Class<?> targetClass) {
return advisorMethod.equals(method);
}
});
Object proxiedBean = proxyFactory.getProxy();
super.processAmqpListener(rabbitListener, method, proxiedBean, beanName);
} else {
super.processAmqpListener(rabbitListener, method, bean, beanName);
}
}
}
bean的定义如下:
@Bean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
public CustomRabbitListenerAnnotationBeanPostProcessor customRabbitListenerAnnotationBeanPostProcessor() {
return new CustomRabbitListenerAnnotationBeanPostProcessor();
}
它有点难看,但它确实有效。如果有人有更好的解决方案,请分享。
答案 0 :(得分:1)
我认为你要找的是bean-post-processor
这是一个简单的例子: https://www.tutorialspoint.com/spring/spring_bean_post_processors.htm
如果您需要拦截调用,可以将代理包装在返回的实例上。一个很好的例子是org.springframework.validation.beanvalidation.MethodValidationPostProcessor。你也可以扩展org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor。
编辑我只是自己学习这个,所以我希望这是正确的方法来做到这一点,但这对我来说在尝试时很有用
@Component
public class MyInterceptAnnotationBeanPostProcessor
extends AbstractBeanFactoryAwareAdvisingPostProcessor
implements InitializingBean {
public void afterPropertiesSet() {
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(
null,
MyIntercept.class);
this.advisor = new DefaultPointcutAdvisor(pointcut, this.createAdvice());
}
protected Advice createAdvice() {
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("advice");
return arg0.proceed();
}
};
}
}
答案 1 :(得分:1)
您可以继承RabbitListenerAnnotationBeanPostProcessor
并覆盖processListener
方法并在调用超级版本之前修改bean。
然后,用您的子类替换RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME
注册的@EnableRabbit
bean。
或者,只需将您的建议添加到容器工厂的建议链中,并建议所有听众。然后,您可以执行运行时检查以查看是否存在其他注释。