• 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 leechenxiang
    10  * @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 jp
    24      * @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容器内容的bean
    14      *    4、如果匹配成功,则为该bean创建代理对象
    15      *    5、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象
    16      *         如果没有代理对象,则返回对象本身
    17      */
    18     @Test
    19     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

     

     

  • 相关阅读:
    2012搜狗校园招聘笔试题(2)
    T-SQL中只截取日期的日期部分和日期的时间部分
    Delphi XE4 TStringHelper用法详解
    TScreen 类
    TScreen 类
    Delphi中Form的position属性与代码自定义窗体位置
    如何让窗口显示在电脑屏幕中间
    C#中整型数据类型
    C# WinForm开发系列
    SQL中EXCEPT和Not in的区别?
  • 原文地址:https://www.cnblogs.com/leechenxiang/p/5306096.html
Copyright © 2020-2023  润新知