zoukankan      html  css  js  c++  java
  • 4.AOP原理模拟

    AOP   Aspect-Oriented-Programming    面向切面编程

      a)是对面向对象的思维方式的有力补充

    好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码

      a)Filter

      b)Struts2 的 interceptor

    Spring AOP的实现依赖于 Java的 Proxy 类

      1.首先创建目标对象(需要被代理的对象)(即该对象的方法的执行前后有业务逻辑的添加)

      UserService service =  new UserServiceImpl();

      2.创建一个 InvocationHandler,在这个InvocationHandler中,可以指明需要添加的业务逻辑

      Interceptor  interceptor = new  Interceptor ();      //public class Interceptor implements InvocationHandler

     

      3.将目标对象放到 InvocationHandler中,由InvocationHandler 来执行整个业务(添加的业务 + 原来的业务)

      interceptor.setTarget(service);

      

      4.代理对象的创建,在创建时,会参考被代理对象实现的接口,代理对象也去实现这些接口

      另外,每个代理里面帝实有 InvocationHandler 对象存在的

      UserService userProxy = (UserService) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), interceptor);

      如上:userProxy 其实是一个实现了UserService接口的 Proxy对象, 

      //可能这也是为什么  Proxy.newProxyInstance  只能由 接口去接收的原因吧

    注:!!一个类 如果在实现了接口的情况下,来为这个类创建一个代理对象时,实现代理时,用jdk 自带的 Proxy 和 InvocationHandler,来帮你产生代理

      这个类如果没有实现接口,那么它会直接用操作二进制码的类库(cglib.jar)来帮你产生代理的代码

      5.使用代理对象,调用add方法(因为userProxy 是实现了UserService接口的,所以是可以调用的)

        userProxy.add();

        //5.1 一旦代理对象调用 add方法,代理对象会 反射Method m = UserDAO.getClass.getMethod 拿到add方法对应的Method对象

        //5.2 然后调用InvocationHandler 中的 invoke (Object proxy, Method method, Object[] args)

      代理对象 add 方法的调用 实际上就是让 InvocationHandler 去处理了,代理对象负责拿到执行方法必要的条件

    InvocationHandler 的实现类

     1 public class Interceptor implements InvocationHandler {
     2     
     3     //被代理对象
     4     private Object target;
     5     
     6     public Object getTarget() {
     7         return target;
     8     }
     9     public void setTarget(Object target) {
    10         this.target = target;
    11     }
    12     
    13     public Object invoke(Object proxy, Method method, Object[] args)
    14             throws Throwable {
    15         System.out.println("方法要执行了");
    16         //调用被代理对象的方法,指明调用哪个被代理对象 ,用到了哪些参数
    17         method.invoke(target, args);
    18         return null;
    19     }
    20 
    21 }

      

    感觉像是在 被代理的对象上面 先包了一层 InvocationHandler,然后在InvocationHandler上再包了一层 Proxy

      然后调用的时候,先去调用Proxy 的 add方法,调用的时候可以拿到执行add方法所必须的条件参数

      然后内部再去调用  InvocationHandler 的invoke方法,在InvocationHandler 的invoke方法里面,

      有新添加的业务逻辑和 本来要执行方法,通过这个invoke方法的执行,来完成动态的添加和删除在切面上的逻辑,

      而不影响原来的执行代码

    为什么要分 Proxy  和  InvocationHandler

      因为InvocationHandler 获取不到 执行原本的方法 所需要的参数,必须要通过Proxy 给它

      Proxy 又不能完成业务逻辑的增加和删除,所以 各司其职

  • 相关阅读:
    FRAM在智能电子式电表中的应用
    element UI实现动态生成多级表头
    小微信小程序开发相关网站
    响应式开发bootstrap
    媒体查询
    前端导出功能实现的两种方式
    watch监听对象遇坑
    vue中使用v-for时为什么要用到key?为什么不能用index作为key?
    vue中我改变了data中的一个值,但现在视图上没有实时更新,请问我怎么拿到更新后的值?
    python 链接数据库的模块
  • 原文地址:https://www.cnblogs.com/xuzekun/p/7396924.html
Copyright © 2011-2022 走看看