新增AOP切面,统计系统方法耗时。
package com.xyzq.afa.pbank.console.aop;
/**
* Created by YANG on 2017-7-6.
*/
import com.xyzq.afa.util.PBankUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
@Component
@Aspect
public class TimeConsumeLogAspect {
private ThreadLocal<Long> time = new ThreadLocal<Long>();
private ThreadLocal<String> tag = new ThreadLocal<String>();
// @Autowired
// private PermissionService permissionService;
@Around("execution(* com.xyzq.afa.pbank.console.*.service*.*.*Impl.*(..))")
public Object aroundService(ProceedingJoinPoint joinPoint) throws Throwable {
Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString());
// String username = (String) SecurityUtils.getSubject().getPrincipal();
//将参数拼成一个字符串
StringBuffer msg = new StringBuffer();
// retrieve the methods parameter types (static):
final Signature signature = joinPoint.getStaticPart().getSignature();
if (signature instanceof MethodSignature) {
final MethodSignature ms = (MethodSignature) signature;
final Class<?>[] parameterTypes = ms.getParameterTypes();
for (final Class<?> pt : parameterTypes) {
msg.append("Parameter type:").append(pt);
}
}
// retrieve the runtime method arguments (dynamic)
if (logger.isDebugEnabled()) {
for (final Object argument : joinPoint.getArgs()) {
msg.append(" Parameter value:");
msg.append(PBankUtil.getObjectAllAttributes(argument));
}
} else {
for (final Object argument : joinPoint.getArgs()) {
msg.append(" Parameter value:");
msg.append(argument);
}
}
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
//Service执行前记录日志
logger.info("[TagId: {} ]Service Starting. Method : {} ({})", tag.get(), ms.getMethod().getName(),
msg.toString());
//执行目标方法并得到其返回值
Object rtn = joinPoint.proceed(joinPoint.getArgs());
int size = -1;
if (rtn instanceof Collection) {
size = ((Collection) rtn).size();
} else if (rtn instanceof Map) {
size = ((Map) rtn).size();
}
//Service执行后记录日志
if (logger.isDebugEnabled()) {
logger.info("[TagId: {} ]Service Finished. Used time {}ms. Return: {}", tag.get(),
System.currentTimeMillis() - time.get(), rtn);
} else {
if (size > -1) {
//集合类型返回值,在非debug模式下只打印集合的size
logger.info("[TagId: {} ]Service Finished. Used time {}ms. Return: {}", tag.get(),
System.currentTimeMillis() - time.get(), size);
} else {
//非集合类型返回值,则直接打印
logger.info("[TagId: {} ]Service Finished. Used time {}ms. Return: {}", tag.get(),
System.currentTimeMillis() - time.get(), rtn);
}
}
return rtn;
}
@Before("execution(* com.xyzq.afa.pbank.console.web.controllers.*.*Controller.*(..))")
public void beforeController(JoinPoint joinPoint) {
Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString());
//将参数拼成一个字符串
StringBuffer msg = new StringBuffer();
// retrieve the methods parameter types (static):
final Signature signature = joinPoint.getStaticPart().getSignature();
if (signature instanceof MethodSignature) {
final MethodSignature ms = (MethodSignature) signature;
final Class<?>[] parameterTypes = ms.getParameterTypes();
for (final Class<?> pt : parameterTypes) {
msg.append("Parameter type:").append(pt);
}
}
// retrieve the runtime method arguments (dynamic)
if (logger.isDebugEnabled()) {
for (final Object argument : joinPoint.getArgs()) {
msg.append(" Parameter value:");
msg.append(PBankUtil.getObjectAllAttributes(argument));
}
} else {
for (final Object argument : joinPoint.getArgs()) {
msg.append(" Parameter value:");
msg.append(argument);
}
}
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
// //确认用户登入信息
// User loginUser = permissionService.getLoginUser();
// logger.debug("[TagId: {} UserName {} ]Controller Starting. Method : {} ({})", tag.get(), (String) SecurityUtils.getSubject().getPrincipal(),
// ms.getMethod().getName(), msg.toString());
logger.info("[TagId: {} ]Controller Starting. Method : {} ({})", tag.get(),
ms.getMethod().getName(), msg.toString());
}
@After("execution(* com.xyzq.afa.pbank.console.web.controllers.*.*Controller.*(..))")
public void afterController(JoinPoint joinPoint) {
Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
// logger.info("[TagId: {} UserName {} ]Controller Succeeded. Used time {}ms. Method : {}{}", tag.get(), (String) SecurityUtils.getSubject().getPrincipal(),
// calendar.getTimeInMillis() - time.get(), ms.getMethod().getName(), ms.getParameterNames());
logger.info("[TagId: {} ]Controller Succeeded. Used time {}ms. Method : {}{}", tag.get(),
calendar.getTimeInMillis() - time.get(), ms.getMethod().getName(), ms.getParameterNames());
}
}
配置XML文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-lazy-init="true">
<context:annotation-config />
<context:component-scan base-package="com.xyzq" />
<aop:aspectj-autoproxy proxy-target-class="false" />
<bean name="bartPlaceholderConfigurer" class="com.xyzq.simpson.bart.client.spring.BartPlaceholderConfigurer">
<property name="location" value="classpath:config/app.properties" />
</bean>
</beans>
启动项目之后抛异常如下:
:Line 12 in XML document from file [D:\IdeaWorks\PrivateBank_test\pbank-console\pbank-console-web\target\pbank-console-web-1.0.0\WEB-INF\classes\config\spring\applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'aop:aspectj-autoproxy'.
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 12 in XML document from file [D:\IdeaWorks\PrivateBank_test\pbank-console\pbank-console-web\target\pbank-console-web-1.0.0\WEB-INF\classes\config\spring\applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'aop:aspectj-autoproxy'.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at net.paoding.rose.load.context.RoseWebAppContext.loadBeanDefinitions(RoseWebAppContext.java:90)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451)
at net.paoding.rose.RoseFilter.prepareRootApplicationContext(RoseFilter.java:426)
at net.paoding.rose.RoseFilter.initFilterBean(RoseFilter.java:268)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4958)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5652)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1863)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$2.run(Transport.java:202)
at sun.rmi.transport.Transport$2.run(Transport.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:198)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(TCPTransport.java:619)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:684)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:681)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'aop:aspectj-autoproxy'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
... 63 more
原因是schemaLocation缺少AOP相关的XSD配置,在XML文件新增AOP配置后即可解决问题。
修改后如下
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="true">
<context:annotation-config />
<context:component-scan base-package="com.xyzq" />
<aop:aspectj-autoproxy proxy-target-class="false" />
<bean name="bartPlaceholderConfigurer" class="com.xyzq.simpson.bart.client.spring.BartPlaceholderConfigurer">
<property name="location" value="classpath:config/app.properties" />
</bean>
</beans>
再重新启动程序即可正常启动。