代理模式
静态代理
角色分析
1. 抽象角色:一般会使用接口或抽象类
2. 真实角色:被代理的角色
3. 代理角色:代理真实角色,代理真实角色之后一般会有一些附属操作
4. 客 户:访问代理对象的人
代码步骤:
1.接口
//抽象角色
public interface Rent {
void rent();
}
2.真实角色
//真实角色
public class Host implements Rent {
public void rent() {
System.out.println("房东要出租房");
}
}
3.代理角色
//代理角色
public class Proxy implements Rent {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
see();
host.rent();
commission();
}
public void see() {
System.out.println("中介带租客看房");
}
public void commission() {
System.out.println("收取中介费");
}
}
4.客户端访问代理角色
//客户
public class Client {
public static void main(String[] args) {
Host host=new Host();
Proxy proxy=new Proxy(host);
proxy.rent();
}
}
//运行结果:
中介带租客看房
房东要出租房
收取中介费
优缺点
优点
1.可以使真实角色的操作更加纯粹,不用去关注公共的业务
2.公共业务就交给代理角色,实现了业务的分工
3.公共业务发生扩展的时候,方便集中管理
缺点
1.一个真实角色就会产生一个代理角色,代码量翻倍,开发效率变低
动态代理
特点:
1.代理角色:同上
2.动态代理的代理类是自动生成的
3.动态代理分为两大类:
3.1:基于接口---JDK动态代理
3.2基于类--cglib
3.3java字节码---javasist
主要的类:
1.Proxy(代理)
2.invocationHandler(调用处理程序)
代码:
1.抽象对象
public interface Rent {
void rent();
}
2.真实角色
//真实角色
public class Host implements Rent {
public void rent() {
System.out.println("房东要出租房");
}
}
3.得到代理对象并执行方法的工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author liye
* @create 2020-08-15-22:13
*/
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理对象
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
//执行要执行的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质:反射
see();
Object result=method.invoke(rent,args);
commission();
return result;
}
public void see() {
System.out.println("中介带租客看房");
}
public void commission() {
System.out.println("收取中介费");
}
}
4.客户端访问代理角色
//客户
public class Client {
public static void main(String[] args) {
//真实角色
Host host=new Host();
//代理角色
ProxyInvocationHandler pih=new ProxyInvocationHandler();
pih.setTarget(host);
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
//运行结果:
中介带租客看房
房东要出租房
收取中介费
5.万能工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author liye
* @create 2020-08-15-22:13
*/
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
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;
}
}
优点:
1.1:可以使真实角色的操作更加纯粹,不用去关注公共的业务
1.2:公共业务就交给代理角色,实现了业务的分工
1.3:公共业务发生扩展的时候,方便集中管理
1.4:一个动态代理类代理的是一个接口,是一类事物
1.5:一个动态代理类可以代理多个实现了同一个接口的类