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 又不能完成业务逻辑的增加和删除,所以 各司其职

  • 相关阅读:
    target runtime apache v6.0 not defined解决
    java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
    The valid characters are defined in RFC 7230 and RFC 3986问题
    invalid END header解决方法
    You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed问题解决
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    在eclipse中import java web项目时遇到的一些问题并将该项目通过tomcat发布
    java byte转string 涉及到字节流中有中文
    spring+mybatis框架搭建时遇到Mapped Statements collection does not contain value for...的错误
    试试看读一下Zepto源码
  • 原文地址:https://www.cnblogs.com/xuzekun/p/7396924.html
Copyright © 2011-2022 走看看