关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

jdk动态代理实现拦截器

发布时间:2020-01-07 18:05:00

jdk动态代理实现拦截器
定义接口
package com.lean.ssm.chapter2.reflect;
 
import java.lang.reflect.Method;
 
public interface Interceptor {
    /**
     * @param proxy 代理对象
     * @param target 真实对象
     * @param method 方法
     * @param args 运行参数
     * @return 返回TRUE调用真实对象方法,false调用around方法
     */
    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);
}
实现类
package com.lean.ssm.chapter2.reflect;
 
import java.lang.reflect.Method;
 
public class MyInterceptor implements Interceptor {
 
    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("在反射方法前逻辑");
        return false;
    }
 
    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("取代代理对象的方法...");
    }
 
    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("在反射方法后逻辑");
    }
 
}
它实现了所有的接口方法,使用jdk动态代理可以去实现这些方法的调用逻辑了,在jdk动态代理中使用拦截器
package com.lean.ssm.chapter2.reflect;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
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  真实对象
     * @param interceptorClass 拦截器完全限定名
     * @return
     */
    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 ret=null;
        //反射生成拦截器
        Interceptor interceptor=(Interceptor) Class.forName(interceptorClass).newInstance();
        //before返回true调用真实方法,false调用around方法
        if (interceptor.before(proxy, target, method, args)) {
            ret=method.invoke(target, args);
        }else {
            interceptor.around(proxy, target, method, args);
        }
        interceptor.after(proxy, target, method, args);
        return ret;
    }
 
}
拦截器可以进一步简化动态代理的使用方法,使程序变得简单
测试
    /**
     * jdk拦截器
     */
    @Test
    public void testInterceptor(){
        HelloWorld proxy=(HelloWorld) InterceptorJdkProxy
                .bind(new HelloWorldImpl(),"com.lean.ssm.chapter2.reflect.MyInterceptor");
        proxy.sayHelloWorld();
    }
输出
在反射方法前逻辑
取代代理对象的方法...
在反射方法后逻辑


/template/Home/Zkeys/PC/Static