Spring基于XML配置AOP
目录结构:
D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\cn\edu\bjut\service\StudentService.java
package cn.edu.bjut.service; /** * Created by N3verL4nd on 2017/3/24. */ public interface StudentService { public void addStudent(String name); }D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\cn\edu\bjut\service\impl\StudentServiceImpl.java
package cn.edu.bjut.service.impl; import cn.edu.bjut.service.StudentService; /** * Created by N3verL4nd on 2017/3/24. */ public class StudentServiceImpl implements StudentService { @Override public void addStudent(String name) { System.out.println("[添加学生]:" + name); //触发异常通知 // System.out.println( 1 / 0); } }D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\cn\edu\bjut\advice\StudentServiceAspect.java
package cn.edu.bjut.advice; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import java.util.Arrays; /** * Created by N3verL4nd on 2017/3/24. */ public class StudentServiceAspect { //前置通知 public void doBefore(JoinPoint jp) { System.out.println("--------------前置通知-------------"); System.out.println("类名:" + jp.getTarget().getClass().getName()); System.out.println("方法名:" + jp.getSignature().getName()); System.out.println("开始添加学生:" + Arrays.toString(jp.getArgs())); System.out.println("-----------------------------------"); } //后置通知 public void doAfter(JoinPoint jp) { System.out.println("--------------后置通知-------------"); System.out.println("学生添加完成!"); System.out.println("-----------------------------------"); } //环绕通知 public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("--------------环绕通知-------------"); System.out.println("添加学生前:"); Object retVal = null; retVal= pjp.proceed(); System.out.println("返回值:" + retVal); System.out.println("添加学生后!"); System.out.println("-----------------------------------"); return retVal; } //返回通知 public void doAfterReturning(JoinPoint jp) { System.out.println("--------------返回通知-------------"); System.out.println("-----------------------------------"); } //异常通知 public void doAfterThrowing(JoinPoint jp, Throwable ex) { System.out.println("--------------异常通知-------------"); System.out.println("异常信息:" + ex.getMessage()); System.out.println("-----------------------------------"); } }D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\cn\edu\bjut\test\T.java
package cn.edu.bjut.test; import cn.edu.bjut.service.StudentService; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by N3verL4nd on 2017/3/24. */ public class T { private ApplicationContext context = null; @Before public void setUp() { context = new ClassPathXmlApplicationContext("beans.xml"); } @Test public void test() { StudentService studentService = (StudentService) context.getBean("studentService"); studentService.addStudent("lgh"); } }D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\beans.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: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="studentServiceAspect" class="cn.edu.bjut.advice.StudentServiceAspect"/> <bean id="studentService" class="cn.edu.bjut.service.impl.StudentServiceImpl"/> <aop:config> <aop:aspect ref="studentServiceAspect"> <aop:pointcut id="businessService" expression="execution(public void cn.edu.bjut.service.impl.StudentServiceImpl.addStudent(String))"/> <aop:before method="doBefore" pointcut-ref="businessService"/> <aop:after method="doAfter" pointcut-ref="businessService"/> <aop:around method="doAround" pointcut-ref="businessService"/> <aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/> <aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/> </aop:aspect> </aop:config> </beans>输出:
--------------前置通知-------------
类名:cn.edu.bjut.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:[lgh]
-----------------------------------
--------------环绕通知-------------
添加学生前:
[添加学生]:lgh
--------------返回通知-------------
-----------------------------------
返回值:null
添加学生后!
-----------------------------------
--------------后置通知-------------
学生添加完成!
-----------------------------------
介绍一下org/aspectj/lang/JoinPoint.java
AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕增强时,使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口。
任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息。我们先来了解一下这两个接口的主要方法:
1)JoinPoint
java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;
Signature getSignature() :获取连接点的方法签名对象;
java.lang.Object getTarget() :获取连接点所在的目标对象;
java.lang.Object getThis() :获取代理对象本身;
2)ProceedingJoinPoint
ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法:
java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;
java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。