zoukankan      html  css  js  c++  java
  • 对AOP切面的一些整理与理解

      首先上一张AOP的图示

    一:几个重要的概念
      1> 切面:横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象[验证切面。日志切面]
      2> 通知:切面中的每个方法
      3> 目标:被通知的方法(业务逻辑中的方法)
      4> 代理(proxy):向目标对象应用通知之后创建的对象
      5> 连接点:程序运行前的某个特定位置(详细的物理存在):如某个方法调用前,调用后,方法抛出异常后等。

    连接点由两个信息确定:方法表示的程序运行点相对点表示的方位。

      6> 切点:每一个类会有多个连接点(看不到摸不到,非详细物理存在)[通过切点能够定位到非常多个连接点]即:连接点是程序类中客观存在的事务。

    AOP通过切点定位到特定的链接点。

    类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一一相应的关系,一个切点匹配多个连接点。切点通过接口进行描写叙述。使用类和方法作为连接点的查询条件。


    二:Spring AOP
      1)增加jar包
      2)在配置文件里增加aop的命名空间(namespace),完整命名空间例如以下:
        <?xml version="1.0" encoding="GB18030"?

    >

        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:aop="http://www.springframework.org/schema/aop"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
                                   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                   http://www.springframework.org/schema/aop
                                   http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
        </beans>
      3)基于注解的方式
         1.在配置文件里增加该配置
         <!-- 启动用JDK动态代理完毕对Aop的支持,支持注解的形式 -->
         <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 
         
         2.配置切面及业务逻辑对象  
         但在 spring4.0 能够配置自己主动扫描的包。仅仅须要包命明白就可以
         <context:component-scan   base-package="" />
        
         spring2.0不具备该属性。正确配置例如以下:1》切面 2》业务逻辑对象
         <!-- 切面 -->
         <bean id="checkAspect" class="com.inspur.aop.impl.CheckAspect"></bean>
         <!-- 业务逻辑对象 -->
         <bean id="calculator"  class="com.inspur.aop.impl.CalculatorLightImpl"> 
         </bean> 

         3.通过代码进行展示 testspring2
        package com.inspur.aop.impl;
        import java.util.Arrays;
        import java.util.List;
        import org.aspectj.lang.JoinPoint;
        import org.aspectj.lang.annotation.Aspect;
        import org.aspectj.lang.annotation.Before;
        import org.aspectj.lang.annotation.Pointcut;
        @Aspect
        public class CheckAspect {
             /**
              * 切入点 做标识使用 特征:private void 方法名(){ }
              */
             @Pointcut("execution(* com.inspur.aop.impl.*.*(..))")
             public void allCalMethod() {}

             @Before("allCalMethod()")
             public void check(JoinPoint joinPoint) {
              //两种方法获取參数的值
              /*// 取得參数的值
                 Object[] objects = joinPoint.getArgs();
                 if (objects != null && objects.length > 0) {
                     for (Object arg : objects) {
                         System.out.println(arg);
                     }
              }*/
               String methodName = joinPoint.getSignature().getName();
               System.out.println(" methodName " + methodName);
               List<Object> args = Arrays.asList(joinPoint.getArgs());
               System.out.println(" the method " + methodName + " begin with " + args);
            }
        }
        
        另:切入点事实上能够不进行书写,仅作为标识使用。

            如不写,则在通知(@befor,@after等)中写进运行语句
                即@Before("execution(* com.inspur.aop.impl.*.*(..))")
            也能够实现作为切面的功能。
    面向切面编程是面向对象编程的一种改进。他的出如今于解决两大问题:(详见testSpring2项目)
      1.代码混乱:越来越多的非业务需求(日志和校验等)增加后,原有的业务方法急剧膨胀, 每一个方法在处理核心业务逻辑时,还必须兼顾其它多个关注点。
      2.代码分散:以日志需求为例。仅仅是为了满足这个单一的需求,就不得不在多个模块 里面多次反复同样的日志代码。

    假设日志代码发生改变,也必须改动全部模板。[核心代码须要写入众多的输出语句,代码冗余及维护困难等各种问题]


    从上述代码引申三个问题:
    1.切入点的定义[execution:运行]
    ·随意公共方法的运行
      execution(public * *(..))
    ·随意一个以‘set’開始的方法的运行
      execution(* set*(..))
    ·AccountService接口的随意方法的运行
    execution(* com.xyz.service.AccountService.(..))
    ·定义在service包里随意方法的运行(最为经常使用)
      execution(* com.xyz.service.*.*(..))
    ·定义在service包或子包里随意方法的运行
     )
    2.Adivce。通知的类型
     ·前置通知 @Before
     ·后置通知 @After
     ·返回后通知
     ·异常抛出后通知
     ·围绕通知
    3.JoiPoint方法:不论什么一个增强方法都能够通过将第一个入參声明为 JoinPoint 訪问到连接点上下文的信息。(简化日志)
      AspectJ 使用 org.aspectj.lang.JoinPoint 接口表示目标类连接点对象。假设是围绕增强时,使用org.aspectj.lang.ProceedingJoinPoint 表示连接点对象,该类是 JoinPoint 的子接口。

    不论什么一个增强方法都能够通过将第一个入參声明为 JoinPoint 訪问到连接点上下文的信息。我们先来了解一下这两个接口的主要方法: 
    1) JoinPoint 
     java.lang.Object[] getArgs():获取连接点方法执行时的入參列表。 
     Signature getSignature() :获取连接点的方法签名对象。 
     java.lang.Object getTarget() :获取连接点所在的目标对象; 
     java.lang.Object getThis() :获代替理对象本身; 
    2) ProceedingJoinPoint 
       ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于运行连接点方法的方法: 
     java.lang.Object proceed() throws java.lang.Throwable:通过反射运行目标对象的连接点处的方法; 
     java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射运行目标对象连接点处的方法,只是使用新的入參替换原来的入參。

      上面的代码提到了两种获取參数的方法。重点记住各个方法的类型及遍历的方式。


  • 相关阅读:
    阿里云ECS linux通过rinetd 端口转发来访问内网服务
    阿里云ECS linux通过iptables 配置SNAT代理网关,实现局域网上网
    适用于CentOS6.x系统的15项优化脚本
    ELK学习笔记
    MAC OSX环境下cordova+Ionic的安装配置
    Windows下 VM12虚拟机安装OS X 10.11 和VM TOOLS
    cordova 下载更新
    android adb常用命令
    ionic实现双击返回键退出功能
    ionic ngCordova插件安装
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6792456.html
Copyright © 2011-2022 走看看