使用Spring AOP 的@AspectJ记录日志
Spring AOP中的三个概念
- advice,向程序内部注入的代码
- pointcut,注入advice的位置,切入点
- advisor,将advice注入预定位置的代码
@AspectJ是基于注解的,所以需要JDK5.0以上的支持
一、最简单的打印一些东西出来
步骤:
- 创建一个Aspect类
- 配置Spring的配置文件
Aspect类中内容如下:
package com.demo.aop.log;
import
org.aspectj.lang.annotation.After;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Before;
import
org.springframework.stereotype.Component;
@Component
@Aspect
public
class
LogAspect {
@Before
(value =
"execution(public * com.demo.service..*.*(..))"
)
public
void
beforeShow() {
System.
out
.println(
"before show."
);
}
@After
(value =
"execution(public * com.demo.service..*.*(..))"
)
public
void
afterShow() {
System.
out
.println(
"after show."
);
}
}
解释:
在
LogAspect的类声明上加上
@Aspect
注解
在
LogAspect类中的方法上加上
@Before
注解,
(value =
"execution(public * com.demo.service..*.*(..))"
)
上面括号指定了所监视的类中的方法,上面代码中监视了com.demo.service包中的所有类的所有方法
application.xml中内容如下:
<?xml version="1.0" encoding= "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:flex="http://www.springframework.org/schema/flex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" >
<aop:aspectj-autoproxy />
<bean class="com.demo.aop.log.LogAspect" />
</beans>
解释:
<bean />
节点指定了
LogAspect.java
的路径
二、将Pointcut和Advice分开,并将方法名和参数打印出来
步骤:
- 创建Pointcut
- 创建Advice
- 配置Spring的配置文件
LogPointcut.java中内容如下:
package
com.demo.aop.log;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Pointcut;
@Aspect
public
class
LogPointcut {
@Pointcut
(
"execution(* com.demo.service..*.*(..))"
)
public
void
inServiceLayer() { }
}
解释:
加上
@Aspect
注解
@Pointcut
是切入点,指定需要注入代码的位置,如上面代码中指定在
com.demo.service
包下的所有类的所有方法中
下面只需要定义一个方法签名
LogAdvice.java中的内容如下:
package
com.demo.aop.log;
import
org.aspectj.lang.JoinPoint;
import
org.aspectj.lang.annotation.After;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Before;
@Aspect
public
class
LogAdvice {
/**
* 在方法开始前纪录
*
@param
jp
*/
@Before
(
"com.demo.aop.log.LogPointcut.inServiceLayer()"
)
public
void
logInfo(JoinPoint jp) {
String className = jp.getThis().toString();
String methodName = jp.getSignature().getName();
//获得方法名
System.
out
.println(
"====================================="
);
System.
out
.println(
"====位于:"
+className);
System.
out
.println(
"====调用"
+methodName+
"方法-开始!"
);
Object[] args = jp.getArgs();
//获得参数列表
if
(args.
length
<=0){
System.
out
.println(
"===="
+methodName+
"方法没有参数"
);
}
else
{
for
(
int
i=0; i<args.
length
; i++){
System.
out
.println(
"====参数 "
+(i+1)+
":"
+args[i]);
}
}
System.
out
.println(
"====================================="
);
}
/**
* 在方法结束后纪录
*
@param
jp
*/
@After
(
"com.demo.aop.log.LogPointcut.inServiceLayer()"
)
public
void
logInfoAfter(JoinPoint jp) {
System.
out
.println(
"====================================="
);
System.
out
.println(
"===="
+jp.getSignature().getName()+
"方法-结束!"
);
System.
out
.println(
"====================================="
);
}
}
解释:
@Before
使用Pointcut中的方法签名找到切入点
记录并打印日志
application.xml配置文件中加入如下配置:
<
aop:aspectj-autoproxy
/>
<bean class="com.demo.aop.log.LogAspect" />