Проблема такая же, как и этот вопрос
Я работаю с Spring AOP в аспекте аннотации, один из моих bean-компонентов не может установить совет по аннотации, но другие могут.
Затем я отлаживаю и выяснил причину, код в BeanFactoryAdvisorRetrievalHelper
указывает, что если advice bean
находится в процессе создания, serviceBean
не сможет установить советник.
if (this.beanFactory.isCurrentlyInCreation(name))
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
перехватчик
public class DemoInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//do something
return new Object();
}
}
Конфигурация советника
config way 1
public class DemoAdvisor implements PointcutAdvisor {
private MethodInterceptor methodInterceptor;
private Pointcut pointcut;
public DemoAdvisor(MethodInterceptor methodInterceptor) {
this.methodInterceptor = methodInterceptor;
this.pointcut = new AnnotationMatchingPointcut(null, DemoAnno.class);
}
@Override
public Advice getAdvice() {
return this.methodInterceptor;
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
@Configuration
public class AnnoAspectConfig {
@Bean
public DemoAdvisor DemoAdvisor() {
DemoAdvisor advisor = new DemoAdvisor(demoInterceptor());
return advisor;
}
@Bean
public DemoInterceptor demoInterceptor() {
DemoInterceptor demoInterceptor = new DemoInterceptor();
return demoInterceptor;
}
}
Тогда я думаю, что это может быть проблема в конфиге совета, поэтому я изменяю совет конфиг ниже:
config way 2
@Configuration
public class ValidationAdvisor {
@Bean
public DefaultPointcutAdvisor demoAdvisor() {
DemoInterceptor interceptor = new DemoInterceptor();
AnnotationMatchingPointcut annotationMatchingPointcut = AnnotationMatchingPointcut.forMethodAnnotation(DemoAnno.class);
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(annotationMatchingPointcut);
advisor.setAdvice(interceptor);
return advisor;
}
}
Затем все идет поиск, поэтому вопрос, почему config way 1
вызывает сбой установки советника, в то время как config way 2
не сделал