Content Table

AspectJ with Xml

需要添加依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.1</version>
</dependency>

spring-beans.xml

pointcut 表示需要织入切面的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

<bean id="service" class="service.Service"/>
<bean id="callAdvice" class="aop.CallAdvice"/>

<!--使用 XML 配置 AOP-->
<aop:config>
<!-- callAdvice 为实现 AOP 的 bean -->
<aop:aspect ref="callAdvice">
<!-- 切入点 pointcut,匹配 expression 的方法会被拦截 -->
<aop:pointcut id="methodPointCut" expression="execution(* service.*.*(..))"/>

<!-- 使用 methodPointCut.doBefore() 执行 before 拦截 -->
<aop:before pointcut-ref="methodPointCut" method="doBefore"/>

<!--<aop:after pointcut-ref="methodPointCut" method="doAfter"/>-->
<!--<aop:around pointcut-ref="methodPointCut" method="doAround"/>-->
<!--<aop:after-throwing pointcut-ref="methodPointCut"
method="doThrowing" throwing="ex"/>-->
</aop:aspect>
</aop:config>
</beans>

Service

1
2
3
4
5
6
7
package service;

public class Service {
public void foo() {
System.out.println("service.Service.foo()");
}
}

CallAdvide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class CallAdvice {
public static int steps = 1;

/**
* 方法被执行前调用
* @param jp
*/
public void doBefore(JoinPoint jp) {
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
System.out.println(String.format("[%d: BEFORE METHOD]: %s.%s()", steps++, className, methodName));
}

/**
* 方法被执行后调用
* @param jp
*/
public void doAfter(JoinPoint jp) {
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
System.out.println(String.format("[%d: AFTER METHOD]: %s.%s()\n", steps++, className, methodName));
}

/**
* 方法被执行时调用
* @param pjp
* @return
* @throws Throwable
*/
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
int sn = steps++;

System.out.println(String.format("[%d: METHOD BEFORE]: %s.%s()", sn, className, methodName));

long time = System.currentTimeMillis();
Object retVal = pjp.proceed();
time = System.currentTimeMillis() - time;

System.out.println(String.format("[%d: METHOD AFTER]: %s.%s() : %dms\n", sn, className, methodName, time));

return retVal;
}

/**
* 异常抛出后调用
* @param jp
* @param ex
*/
public void doThrowing(JoinPoint jp, Throwable ex) {
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
System.out.println(String.format("[%d: THROW EXCEPTION]: %s.%s()\n", steps++, className, methodName));
System.out.println(ex.getMessage());
}
}

AspectJXmlAOPTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.Service;

public class AspectJXmlAOPTest {
private static ApplicationContext context;

@BeforeClass
public static void setup() {
context = new ClassPathXmlApplicationContext("spring-beans.xml");
}

@Test
public void test() {
// service 是 Spring 生成的代理类的对象
Service service = context.getBean("service", Service.class);
service.foo();
System.out.println(service.getClass());
}
}

输出

1
2
3
-[1: BEFORE  METHOD]: service.Service.foo()
service.Service.foo()
class service.Service$$EnhancerBySpringCGLIB$$4848b473