设计模式之动态代理
目录
上文介绍了静态代理,本文介绍动态代理。
所谓动态,是指代理类是动态生成的,而不是我们提前定义好的。
动态代理实现的方式
- 原生JDK(比较常用)
- CGLIB(需要导包 cloud-cglib.jar )
这里介绍利用原生JDK的方式实现
package study.design.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy {
public static void main(String[] args) {
ProxyInvocationHandler pih = new ProxyInvocationHandler();
Cook d_shef = new Chef();
// 设置需要代理的对象
pih.setTarget(d_shef);
// 动态生成代理类
Cook proxy = (Cook) pih.getProxy();
proxy.cook("番茄炒蛋");
}
}
interface Cook {
void cook(String name);
}
class Chef implements Cook {
@Override
public void cook(String name) {
// 具体的实际实现逻辑
System.out.println("=======厨师做饭啦:"+name+"=======");
}
}
// 用于自动生成代理类
class ProxyInvocationHandler implements InvocationHandler {
// 被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
// 生成得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
// 处理代理实例 并返回结果
/**
*
* @param proxy 代理对象
* @param method 代理对象调用的方法
* @param args
* @return 调用的方法中的参数
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
// 动态代理的本质,是利用反射机制实现
Object result = method.invoke(target, args);
after();
return result;
}
// 预处理
public void before() {
System.out.println("=======食材准备完毕=======");
}
// 后处理
public void after() {
System.out.println("=======厨具清理完毕=======");
}
}
控制台输出:
=======食材准备完毕=======
=======厨师做饭啦:番茄炒蛋=======
=======厨具清理完毕=======
-
优点:只需要定义实现
InvocationHandler
接口的实现类,利用该类的实例对象将托管类的实例对象进行绑定即可实现代理; 动态代理的服务内容不需要像静态代理一样写在每个代码块中,只需要写在invoke()方法中即可,降低了代码的冗余度。 -
缺点:任然需要一个实现接口的实现类。要想不需要接口,可借助
CGLIB
,关于相关的用法,不在本文介绍范围之内。
本文由「黄阿信」创作,创作不易,请多支持。
如果您觉得本文写得不错,那就点一下「赞赏」请我喝杯咖啡~
商业转载请联系作者获得授权,非商业转载请附上原文出处及本链接。
关注公众号,获取最新动态!
历史评论
开始评论