Spring AOP 通过XML方式配置各种通知
上一篇AOP原理补充:http://blog.csdn.net/u013704342/article/details/53290191
本文章代码下载地址:http://download.csdn.net/detail/u013704342/9693828
1.声明一个接口:
package test.aop.service.interfaces;
public interface TestAopServiceInterface {
void save();
void update();
void delete();
void testException()throws Exception;
}
2.创建一个实现类:
package test.aop.service.imp;
import test.aop.service.interfaces.TestAopServiceInterface;
public class TestAopServiceBean implements TestAopServiceInterface {
/* (non-Javadoc)
* @see test.aop.service.TestAopServiceInterfaces#save()
*/
@Override
public void save(){
System.out.println("save方法");
}
/* (non-Javadoc)
* @see test.aop.service.TestAopServiceInterfaces#update()
*/
@Override
public void update(){
System.out.println("update方法");
}
/* (non-Javadoc)
* @see test.aop.service.TestAopServiceInterfaces#delete()
*/
@Override
public void delete(){
System.out.println("delete方法");
}
@Override
public void testException() throws Exception {
System.out.println("测试异常通知");
throw new Exception();
}
}
3.创建一个切面类:
package test.aop.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 切面类
*/
public class TestAspect {
/**
*前通知
*/
public void frontAdvice(){
System.out.println("在被拦截的方法执行前,执行frontAdvice该方法");
}
/**
*后通知
*/
public void afterAdvice(){
System.out.println("在被拦截的方法执行完后,执行afterAdvice方法");
}
/**
*最终通知
*/
public void finallyAdvice(){
System.out.println("在被拦截的方法执行完后最终的finally,执行finallyAdvice方法");
}
/**
*异常通知 (例外通知)
*/
public void exceptionAdvice(){
System.out.println("在被拦截的方法执行出现异常时,执行exceptionAdvice方法");
}
/**
*环绕通知
*包围一个连接点的通知,如方法调用。
*这是最强大的一种通知类型。
*环绕通知可以在方法调用前后完成自定义的行为。
*它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
* @throws Throwable
*/
public void aroundAdvice(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
}
}
4.创建一个名字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-2.5.xsd">
<!-- 注册service的bean -->
<bean id="aopService" class="test.aop.service.imp.TestAopServiceBean"></bean>
<!-- 注册切面类的bean -->
<bean id="testAspect" class="test.aop.aspect.TestAspect"></bean>
<!-- 配置AOP切面 -->
<aop:config>
<!-- 配置切面,我们的切入类是testAspect这个bean-->
<aop:aspect id="myAop" ref="testAspect">
<!-- 举例说明:
任意公共方法的执行:execution(public * *(..))
任何一个以“set”开始的方法的执行:execution(* set*(..))
AccountService 接口的任意方法的执行:execution(* com.test.service.AccountService.*(..))
定义在service包里的任意方法的执行:execution(* com.test.service.*.*(..))
定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.test.service..*.*(..))
定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
最靠近(..)的为方法名,靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..)) -->
<!-- 配置切入点 ,从哪一个类切入。配置test.service 下面所有的类和子包的类-->
<aop:pointcut id="myPointcut" expression="execution(* test.aop.service..*.*(..))"/>
<!-- 配置切入前置通知 method="frontAdvice"执行的方法 切入点是myPointcut-->
<aop:before method="frontAdvice" pointcut-ref="myPointcut"/>
<!-- 配置切入后置通知 -->
<aop:after method="afterAdvice" pointcut-ref="myPointcut" />
<!-- 配置最终通知 -->
<aop:after-returning method="finallyAdvice" pointcut-ref="myPointcut"/>
<!-- 配置异常通知 -->
<aop:after-throwing method="exceptionAdvice" pointcut-ref="myPointcut"/>
<!-- 配置环绕通知 -->
<aop:around method="aroundAdvice" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
5.最后创建一个测试类,对通知进行测试,我只测试了save方法和testException方法,感兴趣的可以下载源码进行运行。
package junit.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.aop.service.interfaces.TestAopServiceInterface;
public class TestAop {
@Test
public void test() {
try {
ApplicationContext con = new ClassPathXmlApplicationContext("Spring-Aop.xml");
TestAopServiceInterface aopService = (TestAopServiceInterface)con.getBean("aopService");
aopService.save(); //测试配置的通知
aopService.testException();//测试配置的异常通知
} catch (Exception e) {
e.printStackTrace();
}
}
}