• AOP面向切面编程


    1.什么是AOP

    AOP 指的是面向切面编程——针对业务过程中的切面(相同代码)进行提取,面对的是处理过程中的某一步骤或阶段

    2.AOP作用

    AOP 关注点是共同处理,可以通过配置将其作用到某一个或多个目标对象上。好处是实现组件重复利用,改善程序结构,提高灵活性。将共通组件与目标对象解耦。

    AOP主要用在处理共通逻辑,如性能统计、日志记录、事务处理、异常处理等,利用AOP可以将这些共通逻辑从普通的业务逻辑代码中分离处理。如果要修改这些逻辑也不会影响普通业务逻辑代码。

    3.基本概念及原理

    切面(Aspect):封装共通代码的组件,可以作用到其他目标组件的方法上。

    目标(target):一个或多个方面所作用的对象

    切入点(Pointcut):用于指定哪些组件哪些方法使用切面组件,Spring提供表达式来实现该指定

    方法限定表达式:execution(返回值类型 方法名(参数))

    通知(Advice):用于指定组件作用到目标组件的具体位置

    4.AOP实现原理:基于动态代理技术

    5.AOP开发步骤

    xml配置方式:

    A.创建切面组件类

    B.spring配置文件中申明切面组件

    C.spring配置文件中使切面组件作用到目标组件的方法上

     1     <aop:config>
     2     <!-- aop:pointcut 设置切入点   即哪些类的哪些方法需要使用切面组件切入功能 
     3         expression:通过设置切入点表达式来控制切入点
     4         按类型匹配的切入点表达式
     5         within(包名.类名)
     6         a.匹配到具体的类 如  within(com.rong.web.service.EmpServiceImpl)   
     7     -->
     8         <aop:pointcut expression="within(com.rong.web.service.EmpServiceImpl)" id="myPointcut"/>
     9         <!-- 
    10         aop:aspect 设置切面功能   ref用来指定哪个切面类
    11          -->
    12         <aop:aspect id="" ref="myLogger">
    13             <!-- 设置通知类型 -->
    14             <!-- aop:before  前置通知,在目标方法执行前来执行切面操作
    15                 method:指定切面类哪个方法进行切面操作
    16                 pointcut-ref:设置上面定义好的切入点对象  
    17              -->
    18             <!-- <aop:before method="doBefore"   pointcut-ref="myPointcut"/> -->
    19             <!--后置通知-->
    20             <aop:after method="doAfter" pointcut-ref="myPointcut"/>
    21             <!-- 环绕通知 -->
    22             <!-- <aop:around method="doAound" pointcut-ref="myPointcut"/> -->
    23             <!-- 异常通知 
    24             throwing:需要指定当前的异常对象  需要与切面类的异常通知方法中的参数名对应
    25             -->
    26             <aop:after-throwing method="doException" throwing="e" pointcut-ref="myPointcut" />
    27             <aop:after-returning method="doAfterReturning" pointcut-ref="myPointcut"/>
    28         </aop:aspect>
    29     </aop:config>

    通知类型:

    前置通知(before):先执行切面功能再执行目标功能

    后置通知(after):先执行目标功能再执行切面功能(无异常情况)

    最终通知(after-returning):先执行目标功能再执行切面功能(有无异常都执行切面)

    异常通知(after-throwing):先执行目标,捕获抛出异常后执行切面

    环绕通知(around):先执行切面前置部分,然后执行目标,最后再执行切面后置部分

    切入点表达式:

    类匹配: 语法within(包名.类名)

         匹配到具体的类

    方法匹配:

        execution(返回值类型  包名.类名.方法名(参数类型,参数类型..))

    注解方式实现AOP:

    A.xml配置文件中开启组件扫描和注解功能

      <context:component-scan base-package="com.rong.web"/>

      <aop:aspectj-autoproxy proxy-target-class="true"/>

    B.目标组件注解

    C.切面组件注解

    @Component:声明普通、一般组件

    @Aspect:声明切面组件

    @Before("within(com..UserBizImpl)"):设置前置通知

    @AfterReturning("within(com..UserBizImpl)"):设置后置通知

    @Around("within(com..UserBizImpl)"):设置环绕通知

    @AfterThrowing(pointcut="within(com..UserBizImpl)",throwing="e"):设置异常通知

    @After("within(com..UserBizImpl)"):设置最终通知

     1 /**
     2  * 切面组件类   定义共通的业务逻辑
     3  * 
     4  * @Aspect: 声明当前bean为切面组件bean 
     5  * @Before(切入点表达式):声明当前方法为前置通知
     6  * 
     7  * 
     8  * within:按类型匹配
     9  * within(包名.类名):给某个具体类的所有方法进行aop切面编程
    10  * within(包名.*): 给当前包下(不包括子包)下的所有类切面编程
    11  * within(包名..*):给当前包下(包括子包)下的所有类切面编程
    12  * 
    13  * execution:按方法匹配    
    14  * execution(返回值类型 包名.类名.方法名(参数类型,参数类型,...))
    15  * execution(* com.rong.web.service..*.find*(..)):
    16  *  第一个*是表示任意的方法返回值类型   
    17  *  service..*表示service包和子包下的任意类
    18  *  find*:表示任意以find开头的方法
    19  *  (..)表示方法中的参数任意
    20  * 
    21  * @author 容杰龙
    22  */
    23 //@Aspect
    24 //@Component//声明组件bean注解
     1 public class MyLogger {
     2     
     3     //定义前置通知   在方法执行前执行
     4     //@Before("within(com.rong.web.service.*)")
     5     public void doBefore(){
     6         System.out.println("日志记录前置操作。。。。。。");
     7     }
     8     
     9     
    10     @After("within(com..*)")
    11     //后置通知
    12     public void doAfter(){
    13         System.out.println("日志记录后置通知操作。。。。");
    14     }
    15     
    16     /**
    17      * 
    18      * 给程序中的所有的find开头的方法添加环绕通知
    19      * 
    20      * ProceedingJoinPoint  :  封装了目标组件信息的类
    21      * @param joinPoint
    22      */
    23     
    24 //    @Around("execution(* com.rong.web.service..*.find*(..))")
    25     public void doAound(ProceedingJoinPoint joinPoint){
    26         //getSignature()获取目标方法
    27         String methodName = joinPoint.getSignature().getName();
    28         String className = joinPoint.getTarget().getClass().getName();//获取目标组件类名
    29         
    30         //环绕通知前置功能
    31         System.out.println(className+"的"+methodName+"开始执行......");
    32         long start = System.currentTimeMillis();
    33         
    34         try {
    35             //执行目标组件的方法
    36             Object proceed = joinPoint.proceed();// 等同于empService.findAll()
    37         } catch (Throwable e) {
    38             e.printStackTrace();
    39         }
    40         
    41         //环绕通知后置功能
    42         System.out.println(className+"的"+methodName+"执行完成......");
    43         long end = System.currentTimeMillis();
    44         System.out.println("当前方法总执行时间"+(end-start));
    45     }
    46     
    47     /**
    48      * service和子包所有类中的方法生效
    49      * 异常通知调用的切面方法
    50      * 当发生当前参数类型指定的异常的时候会引发调用,需要注意比当前参数类型大的异常无法引发调用
    51      * 
    52      * pointcut:切入点表达式
    53      * throwing:对应方法中的参数
    54      */
    55     @AfterThrowing(pointcut="execution(* com.rong.web.service..*.*(..))",throwing="e")
    56     public void doException(Exception e){
    57         System.out.println("异常通知调用。。。。。。。。");
    58         e.printStackTrace();
    59     }
    60     
    61     /**
    62      * service包下包括子包的所有方法都执行
    63      * 返回通知    在执行完目标方法返回之前执行  
    64      */
    65     @AfterReturning("execution(* com.rong.web.service..*.*(..))")
    66     public void doAfterReturning(){
    67         System.out.println("返回通知执行......");
    68     }
    69 }
  • 相关阅读:
    微软SmartClient高级开发
    JavaScript教程大全目录( 最后更新:2007/2/27 不断更新中...)
    智能客户端的定义
    JavaScript浏览器输出
    事半功倍系列之javascript
    智能客户端SmartClient (三)
    智能客户端SmartClient (一)
    日文假名输入与键盘对应
    连体词、接续词、接续助词相关
    JavaScript表单
  • 原文地址:https://www.cnblogs.com/57rongjielong/p/7801001.html
Copyright © 2020-2023  润新知