代理模式在 java 开发中是一种比拟常见的设计模式。设计目标在为服务类与客户类之间插入其余性能,插入的性能对于调用者是通明的,起到假装管制的作用,如租房的例子房客、中介、房东。对于代理模式中即:客户类、代理类、委托类(被代理类)。
代理模式的两个设计准则:
1. 代理类与委托类具备类似的行为(独特)
2. 代理类加强委托类的行为
Uml 简图如下:
代理模式实现的形式
- 动态代理
- 动静代理
案例实操
动态代理
为某个对象提供一个代理, 代理角色固定 ,以管制对这个对象的拜访。代理类和委托类有独特的父类和父接口,这样在任何应用委托类对象的中央都能够用代理对象代替。代理类负责申请的预处理、过滤、将申请分派给委托类解决、以及委托类执行完申请后的后续解决。
/**
*
- 接口 形象角色
- 定义行为
*/
public interface Marry {
public void toMarry();
}
/**
- 指标类 实在角色
*/
public class You implements Marry{
@Override
public void toMarry() {
System.out.println(“ 等了这么久,终于等到你。。。“);
}
}
/**
*
- 代理类 代理角色
- 1. 与指标角色实现独特接口
- 2. 持有指标类的援用
- 3. 加强指标角色行为
*/
public class MarryCompany implements Marry{
// 指标角色援用
private Marry target;
public MarryCompany(Marry target) {
this.target = target;
}
public void before(){
System.out.println(“ 婚礼现场缓和安排中 ……”);
}
@Override
public void toMarry() {
before();
target.toMarry();
after();
}
public void after(){
System.out.println(“ 祝贺您胜利进入人生第二阶段 …..”);
}
}
public class Test {
public static void main(String[] args) {
// 结构代理角色同时传入实在角色
MarryCompany marryCompany=new MarryCompany(new You());
marryCompany.toMarry();
}
}
因为动态代理对于代理的角色是固定的,如 dao 层 20 个 dao 类,如果要对办法的拜访权限进行代理,此时须要创立 20 个动态代理角色,引起类爆炸,无奈满足生产上的须要,于是就催生了动静代理的思维。
动静代理
相比于动态代理,动静代理在创立代理对象上更加的灵便,它会依据须要通过反射机制在程序运行期动静的为指标对象创立代理对象,代理的行为能够代理多个办法,即满足生产须要的同时又达到代码通用的目标。动静代理的两种实现形式:
jdk 实现动静代理
对于 jdk 动静代理实现形式比较复杂,回调形式实现底层原理参考: http://rejoy.iteye.com/blog/1627405
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*jdk 动静代理
*/
public class JdkHandler implements InvocationHandler{
// 指标类
private Object target;
public JdkHandler(Object target) {
this.target = target;
}
/**
- 程序运行期动态创建代理角色
- @return
*/
public Object getProxy(){
/**
- 获取代理对象
- 1. 类加载器
- 2. 指标类 实现的接口数组
- 3. 以后类
- @return
*/
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
public void before(){
System.out.println(“ 婚礼现场缓和安排中 ……”);
}
@Override//InvocationHandler 外部参数 以后指标类的办法 参数
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
before();// 加强实在角色行为
Object result= method.invoke(target, args);// 执行实在角色办法
after();// 加强实在角色行为
return result;
}
public void after(){
System.out.println(“ 祝贺您胜利进入人生第二阶段 …..”);
}
}
cglib 动静代理实现(理解)
code generator library,操作字节码。与 jdk 提供的代理区别,Proxy:委托类必须有接口,制作过程比拟快,执行慢;cglib:委托类能够没有接口,继承的思维来实现相似性,制作代理过程比较慢,执行快。次要解决没有接口类的代理实现。
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibInterceptor implements MethodInterceptor {
private Object target;
public CglibInterceptor(Object target) {
this.target = target;
}
// 运行期动态创建代理类
public Object getProxy(){
Enhancer enhancer=new Enhancer();
// 设置父类 class
enhancer.setSuperclass(target.getClass());
// 设置回调对象实现接口的类
enhancer.setCallback(this);
return enhancer.create();
}
public void before(){
System.out.println(“ 婚礼现场缓和安排中 ……”);
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,MethodProxy arg3) throws Throwable {
before();// 加强实在角色行为
Object result= arg3.invoke(target, arg2);
after();// 加强实在角色行为
return result;
}
public void after(){
System.out.println(“ 祝贺您胜利进入人生第二阶段 …..”);
}
}
扩大
UML 示意的相干规定
“可见性”示意该属性对类外的元素是否可见,包含私有(Public)、公有(Private)、受爱护(Protected)和敌人(Friendly)4 种,
在类图中别离用符号 +、-、#、~ 示意。
UML 中的类图有以下几种关系:
依赖关系(带箭头虚线)、
关联关系(带 X 个箭头的实线)、
聚合关系(带空心菱形的实线)、
组合关系(带实心菱形的实线)、
泛化关系(带空心三角箭头的实线)、
实现关系(带空心三角箭头的虚线)、
其中泛化和实现的耦合度相等,它们是最强的。