我试图在我的Spring Boot Web服务项目中添加自定义拦截器。我遵循以下示例并创建了此配置:
package org.example; import java.util.List; import org.aspect.PersistentAspect; import org.springframework.aop.support.AopUtils; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.server.EndpointInterceptor; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; @EnableWs @Configuration public class WsConfig extends WsConfigurerAdapter { @Bean public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { final MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean(servlet, "/v1/*"); } @Bean public XsdSchema schema() { return new SimpleXsdSchema(new ClassPathResource("country.xsd")); } @Bean public Jaxb2Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); String[] jaxbContext = new String[] { "io.spring.guides.gs_producing_web_service" }; marshaller.setContextPaths(jaxbContext); return marshaller; } @Override public void addInterceptors(List<EndpointInterceptor> interceptors) { // aop not working interceptors.add(new CustomValidatingInterceptor(schema(), config())); // aop working // interceptors.add(new CustomValidatingInterceptor(schema(), null)); } @Bean public AppConfig config() { return new AppConfig(); } @Bean public PersistentAspect persistentAspect() { PersistentAspect persistentAspect = new PersistentAspect(); return persistentAspect; } @Bean public Object testAop() { System.out.println("is config aop proxy: " + AopUtils.isAopProxy(config())); return null; } }
但是,当我在addInterceptors方法中添加新的拦截器时,我在配置类中删除了aop代理时遇到了问题。知道为什么吗?整个项目都在git上。
addInterceptors
问题是Spring中的初始化顺序。从技术上讲,因为BeanPostProcessorWS端点(AnnotationActionEndpointMapping在spring- ws中)有一个,它将强制对此需要的任何依赖项(尤其是任何EndpointInterceptorbean )进行早期初始化。
BeanPostProcessor
AnnotationActionEndpointMapping
EndpointInterceptor
解决此问题的一种方法是重新排列BeanPostProcessor,甚至创建您自己的BeanPostProcessor,但通常更容易保留Spring的默认配置- 避免在初始化序列中的其他地方出现类似的意外情况。
避免问题的更简单方法可能是ObjectFactory在EndpointInterceptorbean中使用an 。这将延迟实例化AppConfigbean直到引用它,届时Aop编织也将发生。
ObjectFactory
AppConfig
@Component public class CustomValidatingInterceptor extends PayloadValidatingInterceptor { @Autowired private ObjectFactory<AppConfig> konfigurace; @Override public boolean handleRequest(MessageContext messageContext, Object endpoint) throws IOException, SAXException, TransformerException { System.out.println("is config aop proxy in interceptor: " + AopUtils.isAopProxy(konfigurace.getObject())); return super.handleRequest(messageContext, endpoint); }
显然,这意味着CustomValidatingInterceptor必须将其WsConfig作为已注入(自动装配)的Bean 进行引用。
CustomValidatingInterceptor
WsConfig
感谢您的例子-有一个叉这里使用的ObjectFactory技术。当我从SoapUI发送请求时,这config在所有WsConfig.testAop(),中CountryEndpoint和中都将bean 显示为Aop代理CustomValidatingInterceptor。
config
WsConfig.testAop()
CountryEndpoint