java拦截器中使用的动态代理

java中拦截器内部实际上是通过jdk动态代理实现的

拦截器一般至少有三个方法:before, around, after,用来处理拦截方法的前后逻辑,具体逻辑图如下:

1. 定义拦截器:

/**
 * 定义拦截器接口
 */
public interface Interceptor {
    public boolean before(Object proxy, Object target, Method method, Object[] args);
    public void around(Object proxy, Object target, Method method, Object[] args);
    public void after(Object proxy, Object target, Method method, Object[] args);
}

public class MyInterceptor implements Interceptor {

    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("反射方法前逻辑");
        return false;
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("取代了被代理的方法");
    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("反射方法后逻辑");
    }
}

2. 在JDK动态代理中使用拦截器

定义一个动态代理类,组合进来拦截器,在invoke方法中实现拦截器逻辑

public class InterceptorJdkProxy implements InvocationHandler {

    private Object target;
    private String interceptorClass = null;  //通过拦截器类名引入  

    public InterceptorJdkProxy(Object target, String interceptorClass) {
        this.interceptorClass = interceptorClass;
        this.target = target;
    }

    public static Object bind(Object target, String interceptorClass) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptorClass));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 标识未设置拦截器,可以直接调用原方法返回
        if(interceptorClass == null){
            return method.invoke(target, args);
        }
        Object result = null;
        // 类名反射生成拦截器对象
        Interceptor interceptor = (MyInterceptor)Class.forName(interceptorClass).newInstance();
        if (interceptor.before(proxy, target, method, args)) {
            result = method.invoke(target, args);
        } else {
            interceptor.around(proxy, target, method, args);
        }
        interceptor.after(proxy, target, method, args);
        return result;
    }
}

 真正在invoke方法中实现拦截器的逻辑,内部都是调用了各种反射机制

测试:

public interface HelloWorld{
    public void sayHelloWorld();
}

class HelloWorldImp implements HelloWorld{
    @Override
    public void sayHelloWorld(){
        System.out.println("Hello World!");
    }
}

// ------------------

public class InterceptorTest {
    public static void main(String[] args) {
        HelloWorld hwProxy = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImp(), MyInterceptor.class.getName());
        hwProxy.sayHelloWorld();
    }
}

输出:

 反射方法前逻辑
取代了被代理的方法
反射方法后逻辑

猜你喜欢

转载自www.cnblogs.com/alison-lxj/p/11094126.html