代理模式

2018-11-05  本文已影响0人  剑书藏于西

1、JDK动态代理:

JDK动态代理是实现InvocationHandler接口,然后利用反射新建一个原始类的代理类。

public class JdkProxy implements InvocationHandler {
    private Object target;  // 原始类对象
    public JdkProxy(Object target) {
        this.target = target;
    }

    public void log(Method m) {
        System.out.println(m.getName() + " start");
    }

    /* 
     * proxy 代理对象(一般用不到)
     * method 代理对象要执行的方法
     * args 所需执行方法的参数
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        log(method);    //在执行方法前添加逻辑
        method.invoke(target , args);
        return null;
    }
}
public class TestProxy {
        /*
         * userDAO : 原始对象,实现了UserDAO接口
         * jdkProxy : 给代理添加逻辑的类,最终调用的方法是jdkProxy的invoke()
         * proxy : 通过Proxy的静态方法生成的代理对象
         * 代理对象与原始对象的ClassLoader要一样
         * 通过传入的参数,实现与代理对象同样的接口(或者说代理类是原始类的子类)
         */
         public void testProxy() {
             // new原始对象
             UserDAO userDAO = new UserDAOImpl();

             //将原始对象交给代理类
             JdkProxy jdkProxy = new JdkProxy(userDAO);

             //Proxy.newProxyInstance产生代理对象
             UserDAO proxy = (UserDAO)Proxy.newProxyInstance(
                  userDAO.getClass().getClassLoader(),
                  UserDAO.class.getInterfaces(), 
                  jdkProxy);
             proxy.save(); // 会调用invoke()方法
        }
}

2、CGLib动态代理

JDK Proxy只能代理实现了接口的类,没有实现接口的类就不能实现JDK代理了。这时候就需要CGLib动态代理类,这里需要注意的是实现MethodIntercetor接口,必须导入cglib-nodep-2.1_3.jar这个包。CGLib是针对类来实现代理的,他的原理是对指定的目标生成一个子类。

public class CglibProxy implements MethodInterceptor {
    
    private CglibProxy() {}
    
    public static <T extends Foo> Foo newProxyInstance(Class<T> targetInstanceClazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetInstanceClazz);
        enhancer.setCallback(new CglibProxy());
        return (Foo) enhancer.create();
    }

    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        return proxy.invokeSuper(obj, args);
    }
}
上一篇下一篇

猜你喜欢

热点阅读