代理模式
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);
}
}