1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 9 <!-- 10 1、引入AOP的命名空间 11 xmlns:aop="http://www.springframework.org/schema/aop" 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 14 2、目标类 15 3、切面 16 4、拦截器 由spring内部实现 17 5、aop的配置 18 --> 19 <bean id="personDao" class="cn.test.aop.PersonDaoImpl"></bean> 20 <bean id="transaction" class="cn.test.aop.Transaction"></bean> 21 22 <!-- aop配置 --> 23 <aop:config> 24 <!-- 切入点表达式 25 expression 26 确定哪个类可以生成代理对象 27 id 唯一标识 --> 28 <aop:pointcut expression="execution(* cn.test.aop.PersonDaoImpl.*(..))" id="perform"/> 29 <!-- 切面 --> 30 <aop:aspect ref="transaction"> 31 <!-- 前置通知 32 * 在目标方法执行之前 33 --> 34 <aop:before method="beginTransaction" pointcut-ref="perform"/> 35 <!-- 后置通知 36 * 在目标方法执行之后 37 * 可以根据returning获取目标方法的返回值 38 * 如果目标方法遇到异常,该通知不执行 39 --> 40 <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/> 41 <!-- 前置通知和后置通知只能在目标方法文中添加内容,但是控制不了目标方法的执行 --> 42 <!-- 43 最终通知 44 * 在目标方法执行之后 45 * 无论目标方法是否遇到异常,都执行 46 * 经常做一些关闭资源 47 --> 48 <aop:after method="finallyMethod" pointcut-ref="perform"/> 49 <!-- 50 异常通知 51 目的就是为了获取目标方法抛出的异常 52 --> 53 <aop:after-throwing method="exceptionMethod" throwing="ex" pointcut-ref="perform"/> 54 55 </aop:aspect> 56 </aop:config> 57 58 59 </beans>
Transaction.java1 public class Transaction { 2 //joinPoint 连接点信息 3 public void beginTransaction(JoinPoint joinPoint){ 4 joinPoint.getArgs();//获取方法的参数 5 String methodName = joinPoint.getSignature().getName(); 6 System.out.println(methodName); 7 System.err.println("begin trans action"); 8 } 9 public void commit(JoinPoint joinPoint,Object val){ 10 System.err.println("commit"); 11 } 12 13 public void finallyMethod(){ 14 System.err.println("finally method"); 15 } 16 17 public void exceptionMethod(Throwable ex){ 18 System.err.println(ex.getMessage()); 19 } 20 21 /** 22 * 环绕通知 23 * 能控制目标方法的执行 24 */ 25 26 public void aroundMethod(ProceedingJoinPoint joinPoint){ 27 String methodName=joinPoint.getSignature().getName(); 28 if("addPerson".equals(methodName)){ 29 30 } 31 }
测试:
1 /** 2 * 原理 3 * * 加载配置文件,启动spring容器 4 * * spring容器为bean创建对象 5 * * 解析aop的配置,会解析切入点表达式 6 * * 看纳入spring管理的那个类和切入点表达式匹配,如果匹配则会为该类创建代理对象 7 * * 代理对象的方法体的形成就是目标方法+通知 8 * * 客户端在context.getBean时,如果该bean有代理对象,则返回代理对象,如果没有代理对象则返回原来的对象 9 * 说明: 10 * 如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用 11 * cglibproxy 12 * 13 * */ 14 @Test 15 public void doSome(){ 16 17 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("cn/test/aop/applicationContext.xml"); 18 PersonDao personDao= (PersonDao) applicationContext.getBean("personDao"); 19 20 personDao.addPerson(); 21 22 }
时间: 2024-10-25 21:49:33