java设计模式基础--拦截器

由于动态代理一般比较难理解,一般都会设计一个拦截器接口供开发者使用,这样开发者就只用知道拦截器接口的方法,含义和作用即可,无须知道动态代理是怎么实现的。

以下代码用JDK动态代理来实现一个拦截器的逻辑。

一,定义拦截器接口:

package intercept;import java.lang.reflect.Method;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);}

before方法在真实对象调用前,当返回true时,则反射真实对象,当返回false时,则调用around方法。

二,定义拦截器接口实现类:

package intercept;import java.lang.reflect.Method;public class MyInterceptor implements Interceptor {    @Override    public boolean before(Object proxy, Object target, Method method, Object[] args) {        System.err.println("反射方法前逻辑");                return true;        // return false;// 不反射被代理对象原有方法    }    @Override    public void after(Object proxy, Object target, Method method, Object[] args) {        System.err.println("反射方法后逻辑。");    }    @Override    public void around(Object proxy, Object target, Method method, Object[] args) {        System.err.println("取代了被代理对象的方法");    }}

三,在JDK动态代理(JDK动态代理介绍)中使用拦截器:

package intercept;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 真实对象     * @return 代理对象【占位】     */    public static Object bind(Object target, String interceptorClass) {        //取得代理对象            return Proxy.newProxyInstance(target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                 new InterceptorJdkProxy(target, interceptorClass));    }    @Override    /**     * 通过代理对象调用方法,首先进入这个方法.     *     * @param proxy --代理对象     * @param method --方法,被调用方法     * @param args -- 方法的参数     */        //反射出类对象    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        if (interceptorClass == null) {            //没有设置拦截器则直接反射原有方法            return method.invoke(target, args);        }        Object result = null;        //通过反射生成拦截器        Interceptor interceptor =             (Interceptor) Class.forName(interceptorClass).newInstance();        //调用前置方法        if (interceptor.before(proxy, target, method, args)) {            //反射原有对象方法            result = method.invoke(target, args);        } else {//返回false执行around方法            interceptor.around(proxy, target, method, args);        }        //调用后置方法        interceptor.after(proxy, target, method, args);        return result;    }}

五,定义需要被动态代理的类

因为是JDK动态代理,所以先定义接口:

package intercept;public interface HelloWorld {    public void sayHelloWorld();}

实现接口:

package intercept;public class HelloWorldImpl implements HelloWorld {    @Override    public void sayHelloWorld() {        // TODO Auto-generated method stub        System.out.println("Hello World");    }}

六,编写测试代码:

package intercept;public class TestInterceptor {    public static void main(String[] args) {        HelloWorldImpl obj = new HelloWorldImpl();//被代理对象        String myInterceptor = "com.lean.ssm.chapter2.intercept.MyInterceptor";// 自己定义的拦截器全限定名        HelloWorld proxy = (HelloWorld) InterceptorJdkProxy.bind(obj, myInterceptor);        proxy.sayHelloWorld();    }    }

拦截器可以进一步简化动态代理使用方法,使程序变得简单。

七,参考资料

《java EE 互联网框架整合开发》 杨开振  著

(0)

相关推荐