代理模式(英语:Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问。
代理模式和装饰器模式的共同点:
不改变原有组件的情况下增强其功能
代理模式和装饰器模式的差异:
代理模式可以实现延迟加载,即在需要时才真正创建原有组件,而不是在创建代理时就立即创建原有组件,这对于提高性能和节省资源是有益的。(延迟加载)
代理模式更着重于环绕组件的方式(代理行为)的赋加动作,装饰器模式则是在组件基础上做固有拓展(自身行为)。
代码演示(Java)
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyFactory implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proxy.invokeSuper(obj, args);
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("Method " + method.getName() + " execution time: " + elapsedTime + " ms");
return result;
}
}
// ------------------------------
public class Cat {
public void meow(){
System.out.println("meow~~~meow~~~");
}
}
// ------------------------------
import net.sf.cglib.proxy.Enhancer;
import org.ashe.demo.domain.Cat;
import org.ashe.demo.proxy.ProxyFactory;
public class Ashe {
public static void main(String[] args) {
// 创建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置被代理类的类对象
enhancer.setSuperclass(Cat.class);
// 设置回调函数
enhancer.setCallback(new ProxyFactory());
// 创建代理对象
Cat proxy = (Cat) enhancer.create();
// 调用代理对象的方法
proxy.meow();
}
}
以上代理使用cglib动态代理实现了对Cat对象meow方法的监控,记录了meow方法的执行耗时时间。
值得注意的是被动态代理后,代理对象的所有行为已经被增加行为了,因此给Cat类增加新方法时,代理对象的新方法也会被监控执行耗时。
为什么要代理分为静态代理和动态代理?
-
减少重复代码: 动态代理可以在运行时动态地生成代理对象,不需要手动编写大量的代理类,从而减少了代码量。
-
灵活性: 动态代理可以代理任意接口或类,不需要为每个被代理的类或接口编写一个对应的代理类,提高了系统的灵活性。
-
适应性: 动态代理可以适应接口或类的变化,不需要修改代理类的代码。这种松耦合性使得系统更容易维护和扩展。