代理模式的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务。
- 公共的事情 就交给代理角色 完成,实现了业务的分工。
- 公共业务发生拓展的时候,方便集中管理。
代理模式的缺点:
一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率降低
代理模式的分类
一、静态代理
从前 有某房东有 很多房子需要出租 可是他又懒得去和客户签合同啥的 所以他找了代理…
我们知道 房东 和 代理 有一个相同的 功能 就是 出租房屋
// 租房接口
public interface RentalHouse {
//出租房子
void rentalHouse();
}
房东
//房东 有房子出租的人
public class Host implements RentalHouse {
@Override
public void rentalHouse() {
System.out.println("房东 出租 房子");
}
}
代理
// 代理 帮 房东 出租房子的人
public class Proxy implements RentalHouse {
private Host host;
public Proxy(){}
public Proxy(Host host){
this.host = host;
}
@Override
public void rentalHouse() {
//代理 找房东的出租房
host.rentalHouse();
}
}
客户
public class People {
public static void main(String[] args) {
//房东有房子
Host host = new Host();
//代理 去找房东拿房子
Proxy proxy = new Proxy(host);
//代理将 (房东的)房子 租赁给你
proxy.rentalHouse();
}
}
二、动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是直接写好的
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口 —— JDK动态代理
- 基于类 —— cglib
- java字节码实现 —— javasist
学习动态代理 需了解两个类:
Proxy:代理
Proxy 提供用于 创建动态代理类和实例的静态方法
InvocationHandler:调用处理程序 并返回结果
开始整动态代理案例
RentalHouse接口
// 租房接口
public interface RentalHouse {
//出租房子
void rentalHouse();
}
Host类 房东
//房东 有房子出租的人
public class Host implements RentalHouse {
@Override
public void rentalHouse() {
System.out.println("房东 出租 房子");
}
}
ProxyInvocationHandler类 可以获取动态代理对象 和 执行被代理对象的接口中的方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//此类用于 动态 生成 代理对象 和 执行方法
public class ProxyInvocationHandler implements InvocationHandler {
private Object target; //被代理的目标对象的接口
//使用set注入方式 赋值
public void setTarget(Object target) {
this.target = target;
}
//得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
// 处理 代理实例(就是执行被代理对象的方法)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target, args);
return result;
}
}
测试类
import com.csnz.demo1.Host;
import com.csnz.demo1.RentalHouse;
public class Cilent {
public static void main(String[] args) {
//真实对象
Host host = new Host();
ProxyInvocationHandler invocation = new ProxyInvocationHandler();
//设置要代理的对象
invocation.setTarget(host);
//动态生成代理对象 强转的时候注意 转成 被代理对象的接口类型
RentalHouse proxy = (RentalHouse) invocation.getProxy();
proxy.rentalHouse();
}
}
动态代理的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务。
- 公共的事情 就交给代理角色 完成,实现了业务的分工。
- 公共业务发生拓展的时候,方便集中管理。
- 一个动态代理类代理的是一个接口,对应着一类业务
- 一个动态代理类可以代理多个类,只要实现了同一个接口即可