当调用marshalSendAndReceive时,我正在尝试记录Web服务操作。这样我就可以记录任何使用marshalSendAndReceive的web服务调用,如下所示。但不知何故下面的logWebserviceOperation没有被调用。我的@之前有什么问题吗?还是我错过了什么?
package com.julia;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
package com.julia.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;
import com.julia.service.SOAPConnector;
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_1; //contstants to set the Jaxb context path
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_2;
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_3;
@Configuration
@RefreshScope
public class ParserConfig {
@Value("${application.WSSessionTimeoutInMilliSec}")
private int timeout;
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan(CONTEXT_PATH_1,CONTEXT_PATH_2, CONTEXT_PATH_3);
return marshaller;
}
@Bean
public SOAPConnector soapConnector(Jaxb2Marshaller marshaller) {
SOAPConnector client = new SOAPConnector();
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setConnectionTimeout(timeout);
client.setMessageSender(messageSender);
return client;
}
}
package com.julia.service;
import java.io.IOException;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
import org.springframework.ws.transport.http.HttpUrlConnection;
@Service
@RefreshScope
public class SOAPConnector extends WebServiceGatewaySupport {
private static final Logger LOGGER = LogManager.getLogger(SOAPConnector.class);
public Object callWebService(String url, Object request) {
return getWebServiceTemplate().marshalSendAndReceive(url, request);
}
}
package com.julia.logging;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
private static final Logger LOGGER = LogManager.getLogger(LoggingAspect.class);
public LoggingAspect() {
}
@Before("execution(* org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(..))")
public void logWebserviceOperation(JoinPoint jp) {
Object[] methodArgs = jp.getArgs();
String uri = methodArgs[0].toString();
String payload = String.valueOf(methodArgs[1]);
LOGGER.log("uri:" + uri);
LOGGER.log("payload :" + payload);
}
Spring AOP只能通知Spring容器管理bean。
从共享的代码中,通知所针对的WebServiceTemplate
实例不是Spring bean。
public Object callWebService(String url, Object request) {
return getWebServiceTemplate().marshalSendAndReceive(url, request);
}
WebServiceGatewaySupport.getWebServiceTemplate()方法是从获取WebServiceTemplate
实例的地方获取的。默认逻辑是构造一个新的WebServiceTemplate
类实例。
根据参考文档,WebServiceTemplateBuilder
可用于创建WebServiceTemplate
bean。
WebServiceGatewaySupport.setWebServiceTempate()可以用来设置bean。这样做的时候一定要看笔记。
或者,您可以通知SOAPConnector.callWebService(..)
,它应该提供相同的日志。
@Before("execution(* com.julia.service.SOAPConnector.callWebService(..)) && args(url,request)")
public void logWebserviceOperation(JoinPoint jp,String url, Object request) {
LOGGER.log("uri:" + url);
LOGGER.log("payload :" + request);
}