Использование MethodInterceptor в Spring
У меня есть следующая конфигурация для перехвата метода и применения рекомендаций после возвращения из метода, но следующая конфигурация не работает. Не могли бы вы подсказать, по чему я скучаю?
@Service("txnEventSubscriber")
EventSubscriberImpl
...
@Resource(name="txnEventSubscriber")
private EventSubscriberImpl subscriber;
@Bean
public Advice myAdvice() {
return new AfterReturningAdvice() {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
{
System.out.println("inside advice");
}
};
}
@Bean
public ProxyFactoryBean myProxyFactoryBean() {
return new ProxyFactoryBean() {
private static final long serialVersionUID = 6296720408391985671L;
@PostConstruct
public void afterPropertiesSet() throws ClassNotFoundException {
setTarget(subscriber);
setInterceptorNames(new String[] {"myAdvice"});
}
};
}
У меня есть EventSubscriber, который при вызове и при возврате метода мне нужно перехватить вызов метода и что-то сделать... в этом случае выведите "inside advice".
Я не вижу никаких исключений, просто метод не вызывается.
1 ответ
Прежде всего, я вижу, что у вас есть имя класса как EventSubscriberImpl
и вы вводите тот же тип класса. Это значит, что вы не программируете интерфейсы. В этом случае вы хотели бы setProxyTargetClass(true);
для тебя ProxyFactoryBean
bean и поместите CGLIB в classpath вашего проекта.
Во-вторых, вам нужно что-то вроде этого
@Resource(name="myProxyFactoryBean")
private EventSubscriberImpl subscriber;
всякий раз, когда вы хотите использовать прокси версию вашего EventSubscriberImpl
, Это означает, что вам нужно явно получить этот прокси-компонент по имени прокси-компонента.
В-третьих, я бы использовал что-то вроде этого, чтобы избежать получения компонента по его прокси-имени:
@Resource(name="txnEventSubscriber")
private EventSubscriberImpl subscriber;
@Bean
public Advice myAdvice() {
return new AfterReturningAdvice() {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
{
System.out.println("inside advice");
}
};
}
@Bean
public Advisor myAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(public * com.foo.bar.EventSubscriberImpl.*(..))");
return new DefaultPointcutAdvisor(pointcut, myAdvice());
}