Я понял после учебного кода код учебного пособия по асинхронному методу , что мой источник проблем был: бин с аннотированным методом @Async
не создавался, завернутый в прокси.Я начал копать и понял, что появилось сообщение о том, что
Bean 'NameOfTheBean' не может обрабатываться всеми BeanPostProcessors (например, не имеет права на авто-проксирование)
Здесь вы можете увидеть ответы об этой проблеме и, в основном, о том, что BeanPostProcessors требуются для каждого Бина, поэтому каждый внедренный бин и его зависимости будут исключены для последующей обработки другими BeanPostProcessors, поскольку он поврежденжизненный цикл бобов.Итак, определите, что является BeanPostProcessor
, которое вызывает это, и не используйте и не создавайте bean-компоненты внутри него.
В моем случае у меня была эта конфигурация
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
@Autowired
private Wss4jSecurityInterceptor securityInterceptor;
@Autowired
private DefaultPayloadLoggingInterceptor payloadLoggingInterceptor;
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(securityInterceptor);
interceptors.add(payloadLoggingInterceptor);
}
}
WsConfigurerAdapter
на самом делеBeanPostProcessor
и вы понимаете это, потому что всегда существует шаблон: @Configuration
, который расширяет классы и переопределяет некоторые из его функций для установки или настройки bean-компонентов, участвующих в некоторых нефункциональных функциях, таких как веб-служба или защита.
В вышеупомянутом примере вы должны переопределить addInterceptors
и добавленные bean-объекты-перехватчики, поэтому, если вы используете какую-то аннотацию, например @Async
внутри DefaultPayloadLoggingInterceptor
, она не будет работать.Каково решение?Начните поездку с WsConfigurerAdapter
.Немного покопавшись, я понял, что класс с именем PayloadRootAnnotationMethodEndpointMapping
в конце содержит все допустимые перехватчики, поэтому я сделал это вручную, чтобы переопределить функцию.
@EnableWs
@Configuration
public class WebServiceConfig {
@Autowired
private Wss4jSecurityInterceptor securityInterceptor;
@Autowired
private DefaultPayloadLoggingInterceptor payloadLoggingInterceptor;
@Autowired
public void setupInterceptors(PayloadRootAnnotationMethodEndpointMapping endpointMapping) {
EndpointInterceptor[] interceptors = {
securityInterceptor,
payloadLoggingInterceptor
};
endpointMapping.setInterceptors(interceptors);
}
}
Так что это будет выполнено после всех BeanPostProcessor
сделали свою работу.Функция setupInterceptors
запустится, когда эта сторона закончится, и установит компоненты-перехватчики.Этот вариант использования может быть экстраполирован на такие случаи, как Security.
Выводы:
- Если вы используете @Configuration, выходящую из некоторого класса, который автоматически выполняет некоторые заданные функции, и вы переопределяете их,вы, вероятно, находитесь внутри
BeanPostProcessor
, поэтому не вводите туда bean-компоненты и пытайтесь использовать поведение AOP, потому что оно не будет работать, и вы увидите, что Spring сообщит вам об этом с помощью вышеупомянутого сообщения в консоли.В этих случаях не используйте bean-компоненты, а объекты (с помощью предложения new
). - Если вам нужно использовать bean-компоненты digg о том, какой класс содержит bean-компоненты, которые вы хотите настроить в конце,
@Autowired
it идобавьте эти бобы, как я делал раньше.
Надеюсь, это может сэкономить вам время.