SpringAOP可以用于跟踪某个方法的执行,如在某个方法执行前执行@Before、在某个方法执行后执行@After、在某个方法抛出异常后执行@AfterThrowing、在某个方法返回结果之后执行@AfterReturning以及环绕某个方法执行@Around。
1 添加SpringAOP所需依赖包:
如果是Maven工程,可以设置pom.xml如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gm</groupId>
<artifactId>spring-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-test</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.3.5.RELEASE</spring.version>
<aspectj.version>1.6.11</aspectj.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</project>
2 修改配置文件spring-conf.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop">
<context:component-scan base-package="com.gm.spring_test">
</context:component-scan>
<!-- make the aspectj annotation to be used -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
注意增加aop命名空间以及<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3 新建一个接口Thread:
package com.gm.spring_test;
public interface Thread {
public int run(Object obj);
}
4 新建一个类DownloadFileThreadImpl:
package com.gm.spring_test;
import org.springframework.stereotype.Component;
@Component
public class DownloadFileThreadImpl implements Thread {
public int run(Object obj) {
// TODO Auto-generated method stub
System.out.println("DownloadFileThreadImpl.run()");
return 0;
}
}
注意:用@Component注解类。
package com.gm.spring_test;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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.stereotype.Component;
@Component
@Aspect
public class ThreadAspect {
@Before(value = "execution(* com.gm.spring_test.Thread.run(..))")
public void beforeMethod(JoinPoint jp) {
String methodName = jp.getSignature().getName();
System.out.println(methodName);
System.out.println("before method execute, args are " + Arrays.toString(jp.getArgs()));
}
@After("execution(* com.gm.spring_test.Thread.run(..))")
public void afterMethod(JoinPoint jp) {
System.out.println("after method execute, args are " + Arrays.toString(jp.getArgs()));
}
@AfterThrowing(value="execution(* com.gm.spring_test.Thread.run(..))", throwing="ex")
public void afterThrow(Exception ex) {
System.out.println("afterThrow" + ex.getMessage());
}
@AfterReturning(value="execution(* com.gm.spring_test.Thread.run(..))", returning="result")
public void afterReturn(Object result) {
System.out.println("afterReturn:the result is " + result);
}
@Around(value="execution(* com.gm.spring_test.Thread.run(..))")
public Object aroundMethod(ProceedingJoinPoint pjp) {
Object result = null;
String methodName = pjp.getSignature().getName();
System.out.println(methodName + " start");
try {
result = pjp.proceed();
System.out.println("aroundMethod:the result is " + result);
} catch (Throwable e) {
System.out.println("Exception occurs : "+e.getMessage());
throw new RuntimeException(e);
}
System.out.println(methodName + " end");
return result;
}
}
注意:用@Component以及@Aspect注解类。
6 测试:
package com.gm.spring_test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml");
Thread thread = (Thread) context.getBean("downloadFileThreadImpl");
thread.run("hello world");
}
}
注意:当用DownloadFileThreadImpl来代替程序中的Thread时,程序会报错。
7 结果显示:
run start
run
before method execute, args are [hello world]
DownloadFileThreadImpl.run()
aroundMethod:the result is 0
run end
after method execute, args are [hello world]
afterReturn:the result is 0