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();
    }
}

 

輸出:

 反射方法前邏輯
取代了被代理的方法
反射方法后邏輯

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM