拦截器:动态代理不好理解,所以开发人员就设计了一个拦截器让开发者使用,简化开发(但是实现好难,问题是我还得学。啊啊啊啊啊啊)

定义一个我自己拦截器,目的是加注释,

  • before返回boolean值,他在真实对象之前调用,当返回true时,则反射真是对象的 方法 ,返回false时,调用around方法

  • 在反射真实对象方法或者around之后,调用after

package test.interseptor;

import java.lang.reflect.Method;

import org.aopalliance.intercept.Interceptor;

public class MyInterceptor implements  Interceptor{

    

    public boolean Before(Object proxy, Method  method, Object[] args){

         System.out.println("反射方法前逻辑");

         return false;

         

    }

    public void around(Object proxy, Method  method, Object[] args){

         System.out.println("取代了被代理的方法");

    }

    public void after(Object proxy, Method method,  Object[] args){

         System.out.println("反射方法后的逻辑");

    }

}

package test.interseptor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import org.aopalliance.intercept.Interceptor;

public class InterceptorJDKproxy implements  InvocationHandler{

    private Object target;//真实对象

    private String interceptorClass = null;//拦截器全限定名

    public InterceptorJDKproxy(Object  target,String interceptorClass) {

         this.target=target;

         this.interceptorClass = interceptorClass;

    }

    /*

     * 绑定委托对象,并返回一个【代理占位】

     *

     * @param target 真实对象

     * return 代理对象

     * */

    public static Object bind(Object target,String  interceptorClass) {

         

         return  Proxy.newProxyInstance(target.getClass().getClassLoader(),

                 target.getClass().getInterfaces(),  new InterceptorJDKproxy(target, interceptorClass));

    }

    /*

     * 通过代理对象,调用放啊,首先进入这个invoke方法

     * @param proxy 代理对象

     * @param method 当前调度方法

     * @param args 当前方法参数

     *

     * */

    @Override

    public Object invoke(Object proxy, Method  method, Object[] args) throws Throwable {

         // TODO Auto-generated method stub

         if(interceptorClass==null){

             //假如没有拦截器则直接返回方法

             return  method.invoke(target,  args);

         }

         System.out.println("拦截器在这呢"+interceptorClass);

         Object result = null;

         //如果有拦截器,那么就通过反射创建拦截器

        //这个 MyInterceptor 应该写接口的名字,但是吧,我的那个ssm炸了,继承之后没有参数,我就只好这么写了,Mark下,省的我忘了

         MyInterceptor interceptor =  (MyInterceptor)  Class.forName(interceptorClass).newInstance();

         if(interceptor.Before(proxy, method,  args)){

             //反射原有对象

             result= method.invoke(target, args);

         }

         else{

             //如果是false,就执行round方法

             interceptor.around(proxy, method,  args);

         }

         interceptor.after(proxy, method, args);

         return result;

    }

    

}

package test.interseptor;

import test.jdkproxy.HellowWord;

import test.jdkproxy.HellowWordImpl;

public class TestMyInterceptor {

    public static void main(String[] args) {

         HellowWordImpl proxy = (HellowWordImpl)  InterceptorJDKproxy.bind(new HellowWord(),

                 "test.interseptor.MyInterceptor");

         proxy.SayHellowWord();

    }

}

---------------------------------------------------------------------------------------分割线,输出结果-----------------------------------------------------------------------------------------------------------------

反射方法前逻辑

取代了被代理的方法

反射方法后的逻辑

拦截器大概懂了,无非就是通过接口实现了一个有三个类的对象,然后通过if语句进行逻辑判断,然后还是通过添加到之前的jdk或者CGlib里的invoke或者interceptor方法来执行并不难理解,看看书上的说明,这个拦截器的执行步骤:

  1. 在bind中使用jdk动态代理绑定了一个对象,然后返回代理对象

  2. 如果没有设置拦截器,则直接返回对象的方法,否则执行第三部

  3. 通过反射生成拦截器,并准备使用

  4. 调用拦截器的before方法,如果为true,反射原来的方法,否则,运行拦截器的around方法

  5. 最后调用after方法,

  6. 返回

拦截器的执行过程

3.拦截器

还有个责任链模式,袋盖就是多个拦截器一起用,拦截器的话,before的执行顺序是321,after的执行顺序是123

 

 

 

 

相关文章: