代理模式:为其他对象提供一种代理以控制对对象的访问
主要解决:直接访问对象时带来的问题,比如,要访问的对象在远程机器上,有些对象由于某些原因,创建开销很大,或者操作需要安全控制,或者需要进程外的访问。直接访问会给使用者带来很多麻烦,因此可以在访问对象时加上一个对此对象的访问层。
应用实例:windows快捷方式,spring aop
优点:1 职责清晰 2 高扩展性 3 智能化
缺点:1 在客户端和真实对象之间增加了代理对象,有些类型的代理模式可能会造成请求处理速度变慢。2 实现代理模式需要额外的工作。有些代理模式的实现非常复杂。
使用场景:1. 远程代理 2. 虚拟代理 3. Copy-on-write代理 4. 保护代理(Protect or Access)5. Cache代理 6. 防火墙代理 7. 同步化代理(Synchronization) 8. 智能引用代理(smart reference)
代理模式和适配器模式的区别:适配器模式主要改变所考虑对象的接口,代理模式不能改变所代理类的接口
代理模式和装饰器模式的区别:装饰器模式是为了增强功能,代理模式是为了加以控制。
静态代理实例:
public interface Movable {
void move();
}
public class TankTimeProxy implements Movable {
private Movable tank;
public TankTimeProxy(Movable tank){
this.tank=tank;
}
@Override
public void move(){
long start=System.currentTimeMillis();
System.out.println("start time : " +start);
tank.move();
long end=System.currentTimeMillis();
System.out.println("end time : "+end);
System.out.println("spend all time :"+(end-start)/1000+"s.");
}
}
public class TankLogProxy implements Movable{
private Movable tank;
public TankLogProxy(Movable tank){
this.tank=tank;
}
@Override
public void move(){
System.out.println("tank move start");
tank.move();
System.out.println("tank move end");
}
}
Movable target=new TankLogProxy(new TankTimeProxy(new Tank()));
target.move();
动态代理实例:
public class MyTimeProxyInvokeHandler implements InvocationHandler {
private Object target;
public MyTimeProxyInvokeHandler(Object target){
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
long start=System.currentTimeMillis();
System.out.println("start time :"+start);
method.invoke(target,args);
long end=System.currentTimeMillis();
System.out.println("end time : "+end);
System.out.println("spend all time : "+(end-start)/1000+"s.");
return null;
}
}
Movable tank=new Tank();
MyTimeProxyInvokeHandler myTimeProxyInvokeHandler=new MyTimeProxyInvokeHandler(tank);
Movable tankProxy=(Movable)Proxy.newProxyInstance(tank.getClass().getClassLoader(),tank.getClass().getInterfaces(),myTimeProxyInvokeHandler);
tankProxy.move();
这种方式为JDK的Proxy代理实现,目标类与代理类实现相同的接口,目标类不存在接口,只能使用CGLIB来解决。
CGLIB代理生成原理是生成目标类的子类,子类是增强过的,子类对象就是代理对象。
CGLIB实现代理模式:
public class Tank2 {
public void move(){
System.out.println("Tank Moving ,....");
try{
Thread.sleep(new Random().nextInt(5000));
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class MyTimeProxyInvokeHandler implements InvocationHandler {
private Object target;
public MyTimeProxyInvokeHandler(Object target){
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
long start=System.currentTimeMillis();
System.out.println("start time :"+start);
method.invoke(target,args);
long end=System.currentTimeMillis();
System.out.println("end time : "+end);
System.out.println("spend all time : "+(end-start)/1000+"s.");
return null;
}
}
Tank2 proxyTank=new MyCglibFactory(new Tank2()).myCglibCreator();
proxyTank.move();
参考:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有