• Spring AOP 杂谈


    其实AOP的思想现在讲的已经很多了,本身没有什么难点,难的是AOP有自己的一套术语,而我们经常被这套术语搞晕。术语没招,只能理解背诵了,尽管背诵很讨厌,可大家都这么说,不知道,就会被说晕。

    AOP思想:如下图,面向切面编程。就是“切“。执行自己的方法时,“在之前,之后,异常,返回,或者前后”都去顺便执行一下其他业务方法,切面就是其他业务方法。

    AOP术语如下图,简单示例

    通知:通知定义了切面是什么以及何时使用,首先该通知方法实现了“做什么的代码业务逻辑”,然后确定了在什么时候执行。

    前置通知:在目标方法调用之前调用通知。

    后置通知:在目标方法完成之后调用通知。

    返回通知:在目标方法成功执行之后调用通知。

    异常通知:在目标方法抛出异常后调用通知。

    环绕通知:通知包裹了被通知的方法,在被通知的方法调用之前和之后执行的自定义行为。

    连接点:连接点 是在应用执行过程中能够插入 切面 的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

    切点:切点就是在 “哪个连接点或哪些连接点处”执行通知。定义了何处执行。

    切面:通知+切点=切面 定义了 1.何时2.何处3.干什么 这三要素。

    以下的两个概念定义了如何实现AOP

    引入:引入允许我们向现有的类添加新方法或属性。而无需修改这些现有的类的情况下,让他们具有新的行为和状态。

    织入:是切面应用到目标对象并创建新的代理对象的过程。

    这两个概念都是 “动作”

    在目标对象的生命周期里可以有多个点进行织入(这里要了解一下  java类的运行过程)

    编译期:切面在目标类编译时被织入,这种方式需要特殊的编译器。

    类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。

    运行期:切面在应用运行的某个时刻被织入。(一般情况下,在织入切面时,AOP容器会为目标对象动态的创建一个代理对象)

    AOP实现

    JAVA静态代理 : 代理对象和被代理对象实现相同的接口。

    //接口

    public interface StaticProxy {
             void action();

    }

    //被代理类

    public class BProxy implements StaticProxy {

      @Override
      public void action() {
        System.out.println(BProxy.class.getName()+":做一些事情");
      }

    }

    //代理类

    public class DProxy implements StaticProxy{

      StaticProxy BProxy;

      public DProxy() {
        BProxy = new BProxy();
      }

      @Override
      public void action() {
        System.out.println(DProxy.class.getName()+":先做一些事情");
        BProxy.action();
        System.out.println(DProxy.class.getName()+":再做一些事情");
      }

    }

    JDK动态代理:动态代理类的字节码在程序运行时由Java反射机制动态生成。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。一个类                               和一个接口实现。JDK动态代理的缺点:被代理类必须是实现接口的类。

    //代理类 实现 InvocationHandler 

    public class DynamicProxy implements InvocationHandler {

                   private Object target;

                   public DynamicProxy(Object target) {
                         this.target = target;
                   }

                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                         //目标方法之前执行
                         System.out.println("do sth Before...");
                        //通过反射机制来调用目标类方法
                        Object result = method.invoke(target, args);
                        //目标方法之后执行
                        System.out.println("do sth After... ");
                        return result;
                   }

    }

    //供被代理类实现的接口

    public interface userSrevices {

                public void addUser();

                public void deleteUser();

    }

    //实现接口的被代理类

    public class userSrevicesImpl implements userSrevices{

        @Override
        public void addUser() {
          System.out.println("增加了一个用户");

        }

        @Override
        public void deleteUser() {
          System.out.println("删除了一个用户");
        }

    }

    //测试

    public class test {

    public static void main(String[] args) {
      //被代理类
      userSrevices target = new userSrevicesImpl();
      //代理类
      DynamicProxy handle = new DynamicProxy(target);
      //获取代理
      userSrevices proxy = (userSrevices)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);//Proxy类创建代理对象。
      //执行
      proxy.addUser();
      proxy.deleteUser();
    }

    }

    Cglib动态代理:(目前尚未有实例。。。故引用一哈别的大神的讲解)https://www.cnblogs.com/yangming1996/p/6824249.html

    AspectJ实现:

     

    未完待续。

     

  • 相关阅读:
    let,const及解构赋值
    开发规范
    深入理解javascript之this
    深入理解javascript之作用域
    深入理解javascript之数据存储
    深入理解javascript之定时器
    Android 多选列表对话框 setMultiChoiceItems
    Android 单选列表对话框 setSingleChoiceItems
    Android 列表对话框 setItems
    Android 警告对话框 AlertDialog
  • 原文地址:https://www.cnblogs.com/dev1ce/p/10676721.html
Copyright © 2020-2023  润新知