项目
博客
文档
归档
资源链接
关于我
项目
博客
文档
归档
资源链接
关于我
设计模式之 —— 代理模式
2020-11-12
·
softbabet博主
·
原创
·
设计模式
·
本文共 265个字,预计阅读需要 1分钟。
## 代理模式 为其他对象提供一种代理,以控制对这个对象的访问。**代理对象**在**客户端**和**目标对象**之间起到中介的作用。结构型。 使用场景:包含目标对象,增强目标对象。 优点:代理模式能将代理对象与真实被调用的目标对象分离。 一定程度上降低了系统的耦合度,扩展性好;保护目标对象,增强目标对象。 缺点:造成系统设计中类的数目增加 在客户端和目标对象增加了一个代理对象,会造成请求处理速度变慢;增加系统复杂度。 扩展:静态代理:通过在代码中显示的定义了一个业务实现类的代理。在代理类中对同名的业务方法进行包装,用户通过调用代理类的被包装过业务方法来调用目标对象的业务方法,同时对目标对象的业务方法进行增强。 动态代理:动态代理不能代理类,可以**代理接**口。是通过**接口**中的方法名在动态生成的代理类中调用业务实现类的同名方法。 CGLib代理:可以**代理类**-原理是生成一个代理子类,会覆盖其的方法,就是通过继承重写,所以要注意,这个类是final,是无法继承的;方法是final的,那么这个方法是不能重写的; Spring代理选择: 当Bean有实现接口时,Spring就会用JDK的动态代理; 当Bean没有实现接口时,Spring使用CGLib 可以前置使用CGLib: **在spring配置中加入
** 参考资料:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html 代理速度对比: jdk7/8的JDK动词代理要比 CGLib 快20%左右 相关设计模式: 代理与装饰者模式:装饰者是为对象加上行为,代理模式是控制访问,注重设置代理人的方式来增强目标对象,一般是增强目标对象的某些行为。 代理与适配器模式:适配器模式主要改变所考虑对象的接口 。代理模式是不能改变所代理类的接口的。 ### 静态代理 建立一个代理类,将目标对象注入到代理对象中,代理类中新增同样的目标方法。对此方法扩展同时调用目标对象的此方法 ``` public class OrderServiceStaticProxy { private IOrderService iOrderService; public int saveOrder(Order order){ beforeMethod(order);//扩展调用目标对象前的业务 iOrderService = new OrderServiceImpl(); int result = iOrderService.saveOrder(order);//调用同样方法的目标对象 afterMethod();//扩展调用目标对象后的业务。 return result; } } ``` ### 动态代理 业务接口: ``` public interface Oderse { String save(String name); } ``` 业务实现: ``` public class OderService implements Oderse{ @Override public String save(String name) { System.out.println(name+": 主业务保存"); return name; } } ``` 动态代理: ``` public class OderServiceDynamicProxy implements InvocationHandler { private Object target; public OderServiceDynamicProxy(Object target) { this.target = target; } public Object bind(){ Class cls = target.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object argObject = args[0]; System.out.println(argObject+":业务前处理"); Object object = method.invoke(target,args); System.out.println(object+": 业务后处理"); return object; } } ``` 测试: ``` Oderse oderse = (Oderse)new OderServiceDynamicProxy(new OderService()).bind(); String xx = oderse.save("xx"); ``` ### 源码应用 jdk: Proxy spring:ProxyFactoryBean.getObject() spring-aop:JdkDynamicAopProxy,CglibAopProxy mybatis:MapperProxyFactory.newInstance()