带有 Spring AOP 的 Spring SOAP webservice 端点 [英] Spring SOAP webservice endpoint with Spring AOP
问题描述
我正在使用 spring soap 实现开发 Web 服务,因此我的服务类使用 @Endpoint 注释进行注释.现在,我想将 SPRING AOP 用于我已经实现的应用程序日志记录.但是,正如我所注意到的,在我从切入点表达式中排除我的服务类之前,当我的 web 服务被调用时,我没有发现端点映射异常.当我从 AOP 的范围中排除服务类时,一切又正常了.对此有什么想法吗?
I am developing a webservice using spring soap implementation and hence my service class is annotated with @Endpoint annotation. Now, I want to use SPRING AOP for application logging which I have already implemented. However, as I have noticed, until I execlude my service class from the pointcut expression, I get no endpoint mapping found exception when my webservice is invoked. When I exclude the service classes from AOP's scope, things work fine again. Any idea on this?
更新:
我的记录器类
package com.cps.arch.logging;
@Component
@Aspect
public class LoggerAspect {
private static final Logger logger = LoggerFactory.getLogger("Centralized Payment System");
@Before("(execution(* com.cps..*.*(..)) and not execution(* com.cps.service..*.*(..)))")
public void logBefore(JoinPoint joinPoint) {
logger.info("Execution Start : "+"Class: "+joinPoint.getTarget().getClass().getName()+
"Method: "+joinPoint.getSignature().getName());
}
}
我的服务端点:
package com.cps.service.impl;
@Endpoint
public class EndpointIntegrationServiceImpl implements EndpointIntegrationService
{
private static final String NAMESPACE_URI = "http://www.example.com/cps/model";
@Autowired
public MYBO myBO ;
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "SaveDataRequest")
public void saveData(@RequestPayload
SaveDataRequest data) {
//business layer invocation
}
}
我的 WS 配置
@EnableWs
@Configuration
@ComponentScan(basePackages={"com.cps"})
public class WebServiceConfig extends WsConfigurerAdapter
{
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
@Bean(name = "MyWsdl")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("MyPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.example.com/micro/payment/PaymentManagement");
wsdl11Definition.setSchema(reconciliationSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema schema() {
return new SimpleXsdSchema(new ClassPathResource("XSD/MySchema.xsd"));
}
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(validationInterceptor());
}
@Bean
ValidationInterceptor validationInterceptor() {
final ValidationInterceptor payloadValidatingInterceptor = new ValidationInterceptor();
payloadValidatingInterceptor.setSchema(new ClassPathResource(
"XSD/MySchema.xsd"));
return payloadValidatingInterceptor;
}
}
抱歉,我不得不更改一些变量/类名称以符合公司政策.因此,正如您所看到的,我必须将非执行"部分放在 AOP 中才能使我的 Web 服务正常工作.如果我删除那部分,我会收到 404 错误.
Sorry but I had to change few of the variable/class names to adhere to company policy. So as you can see I had to put the "not execution" part in the AOP to make my webservice work. If I remove that part, I get 404 error.
推荐答案
@Tarun 是对的,虽然我也发现有必要延迟 AppConfig config
bean 的初始化.
@Tarun is right, though I also found it necessary to delay the initialization of the AppConfig config
bean.
因为您(@hudi 的)示例中的 CustomValidatingInterceptor
bean 是一个 EndpointInterceptor
,所以在 Spring 初始化序列的早期需要它.这意味着它在针对 config
bean 的 Aop 编织生效之前被实例化.请注意这里的原始问题中还有一个 EndpointInterceptor
.
Because the CustomValidatingInterceptor
bean in your (@hudi's) example is an EndpointInterceptor
, it is needed early in the Spring initialization sequence. This means it is being instantiated before the Aop weaving against the config
bean has taken effect. Note how there is also an EndpointInterceptor
in the original question here.
避免这种情况的一种方法是使用 ObjectFactory
.这可以从一开始就连接进来,但使 Spring 能够延迟 config
bean 的实际实例化,直到拦截器和 Aop 代理都初始化完毕.
One way to avoid this is to use an ObjectFactory
. This can be wired in from the start, but enables Spring to delay the actual instantiation of the config
bean, until after the interceptor and Aop proxy are both well initialized.
您的问题上有一个例子.这在 SoapUI 中测试良好.
There's an example of this back on your question. This tested fine from SoapUI.
这篇关于带有 Spring AOP 的 Spring SOAP webservice 端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!