当前位置: 代码迷 >> Java相关 >> Spring 一二事(九)
  详细解决方案

Spring 一二事(九)

热度:68   发布时间:2016-04-22 19:12:35.0
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.xml.PersonDAOImpl"></bean> 2     <bean id="transaction" class="com.lee.spring002.aop.xml.Transaction"></bean> 3      4     <aop:config > 5         <!-- 切入点表达式,作用:确定目标类 --> 6         <!-- spring 会自动检测这个表达式下的类是否是切面,如果是,则不会包含进来 --> 7         <aop:pointcut expression="execution(* com.lee.spring002.aop.xml.PersonDAOImpl.*(..))" 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.xml;2 3 public interface IPersonDAO {4     public String savePerson();5 }

PersonDAOImpl.java

 1 package com.lee.spring002.aop.xml; 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.xml; 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.xml; 2  3 import org.junit.Test; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 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 ClassPathXmlApplicationContext("applicationContext.xml");21         IPersonDAO personDAO = (IPersonDAO)context.getBean("personDAO");22         personDAO.savePerson();23     }24 25 }

 

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

 

 

  相关解决方案