你的位置:首页 > Java教程

[Java教程]Spring 一二事(9)


AOP在spring中是非常重要的一个

在切面类中,有5种通知类型:

aop:before  前置通知

aop:after-returning  后置通知

aop:after  最终通知

aop:after-throwing  异常通知

aop:around  环绕通知

 1    <bean id="personDAO" class="com.lee.spring002.aop.></bean> 2   <bean id="transaction" class="com.lee.spring002.aop.></bean> 3    4   <aop:config > 5     <!-- 切入点表达式,作用:确定目标类 --> 6     <!-- spring 会自动检测这个表达式下的类是否是切面,如果是,则不会包含进来 --> 7     <aop:pointcut expression="execution(* com.lee.spring002.aop. id="perform"/> 8     <!-- ref 指向切面 --> 9     <aop:aspect ref="transaction">10       <!-- 前置通知 -->11       <aop:before method="beginTransaction" pointcut-ref="perform"/>12       13       <!-- 14         后置通知15           可以获取目标方法的返回值(前置方法获取不到)16           如果目标方法抛出异常,后置通知则不会继续执行17       -->18       <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>19       20       <!-- 21         最终通知22           无论目标方法是否抛出异常都将执行此方法23       -->24       <aop:after method="finallyDisplay" pointcut-ref="perform"/>25       26       <!-- 27          异常通知28        -->29        <aop:after-throwing method="exception" pointcut-ref="perform" throwing="content"/>30        31        <!-- 32          环绕通知33            能控制目标方法能否执行34            前置通知和后置通知能在目标方法的前后加代码,但是不能控制方法的执行35        -->36        <aop:around method="arround" pointcut-ref="perform"/>37     </aop:aspect>38   </aop:config>

关于切面的表达式简单说一下:

  • 任意公共方法的执行:
    execution(public * *(..))
  • 任何一个名字以“set”开始的方法的执行:
    execution(* set*(..))
  • AccountService接口定义的任意方法的执行:
    execution(* com.xyz.service.AccountService.*(..))
  • 在service包中定义的任意方法的执行:
    execution(* com.xyz.service.*.*(..))
  • 在service包或其子包中定义的任意方法的执行:
    execution(* com.xyz.service..*.*(..))

 

IPersonDAO.java

1 package com.lee.spring002.aop.2 3 public interface IPersonDAO {4   public String savePerson();5 }

PersonDAOImpl.java

 1 package com.lee.spring002.aop. 2  3 public class PersonDAOImpl implements IPersonDAO { 4  5   @Override 6   public String savePerson() { 7     System.out.println("PersonDAOImpl - savePerson()"); 8      9 //    int a = 1 / 0;10     11     return "save successfully";12   }13 14 }

Transaction.java

 

 1 package com.lee.spring002.aop. 2  3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5  6 /** 7  * 这是个切面 8  *  9  * @author leechenxiang10  * @date 2016年1月12日11  *12 */13 public class Transaction {14   15   public void beginTransaction(JoinPoint jp) {16     System.out.println("连接点名称: " + jp.getSignature().getName());17     System.out.println("目标类名称: " + jp.getTarget().getClass());18     System.out.println("Begin transaction...");19   }20   21   /**22    * 23    * @param jp24    * @param val 目标方法返回值,要与returning对应 25   */26   public void commit(JoinPoint jp, Object val) {27     System.out.println("Transaction commit...");28     29     System.out.println("returning: " + val.toString());30   } 31   32   public void finallyDisplay() {33     System.out.println("finally...");34   }35   36   public void exception(JoinPoint jp, Throwable content) {37     System.out.println("exception: " + content);38     System.out.println("exception: " + content.getMessage());39   }40   41   public void arround(ProceedingJoinPoint pjp) throws Throwable {42     System.out.println("arround...");43     pjp.proceed();  // 调用目标方法,如果这行不写,则目标方法不执行44   }45 }

测试:

 1 package com.lee.spring002.aop. 2  3 import org.junit.Test; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPath 6  7 public class TransactionTest { 8  9   /**10    * 原理:11    *  1、当spring容器启动的时候,加载两个bean,对两个bean进行实例化12    *  2、当spring容器对配置文件解析到<aop:config>的时候13    *  3、把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean14    *  4、如果匹配成功,则为该bean创建代理对象15    *  5、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象16    *     如果没有代理对象,则返回对象本身17   */18   @Test19   public void testPerson() {20     ApplicationContext context = new ClassPath);21     IPersonDAO personDAO = (IPersonDAO)context.getBean("personDAO");22     personDAO.savePerson();23   }24 25 }

 

github地址:https://github.com/leechenxiang/maven-spring002-aop