静态代理
原理图
1. 用户只关心接口功能,而不在乎谁提供了功能。上图中接口是 Subject。
2. 接口真正实现者是上图的 RealSubject,但是它不与用户直接接触,而是通过代理。
3. 代理就是上图中的 Proxy,由于它实现了 Subject 接口,所以它能够直接与用户接触。
4. 用户调用 Proxy 的时候,Proxy 内部调用了 RealSubject。所以,Proxy 是中介者,它可以增强 RealSubject 操作。
直接上代码
先定义一个接口
public interface rent {
void rent();
}
一个接口的实现类,其实就是真实被代理的对象
public class host implements rent{
@Override
public void rent() {
System.out.println("出租房子啦");
}
}
加一个代理类
public class proxy {
//真实对象
private host host;
public void setHost(host host) {
this.host = host;
}
//代理对象的业务
public void torent(){
//原本需要做的事情,将真实对象拿过来。
host.rent();
fee();
}
//其他的操作,拓展的
public void fee(){
System.out.println("还要其他的操作哦哦哦");
}
}
一个客户端 ,如果直接访问真实对象,就只输出真实对象的内容。
public class me {
public static void main(String[] args) {
host h=new host();
h.rent();
}
}
运行结果
现在用户通过代理类访问真实对象,可以在真实对象的基础上,添加些附属的功能方法。
public class me {
public static void main(String[] args) {
host h=new host();
proxy proxy=new proxy();
proxy.setHost(h);
proxy.torent();
}
}
运行结果:
以上就是静态代理了,但是如果有多个真实对象的话,静态代理就需要每一个真实对象都要有一个代理对象,这样会创建太多类和重复的方法什么的,代码太沉重了,这就是静态代理最大的缺点。
总结一下
优点:业务更纯粹,不用关注公共部分 交给代理就实现了业务的分工 公共业务发生拓展的时候,方便管理。 缺点:一个真实角色就要一个代理,代码会翻倍
动态代理
静态代理需要自己创建代理类,但是动态代理不需要手动创建,他的底层是用反射实现的,可以在程序运行的时候在内存中创建一个代理类。。
接口和实现类如上,需要创建一个动态代理类,都是死代码,实现的接口是JDK下的。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object obj;
public void setObj(Object obj) {
this.obj = obj;
}
//得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),obj.getClass().getInterfaces(),this );
}
//处理代理实例,返回代理的人
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = method.invoke(obj,args);
s();
return o;
}
void s(){
System.out.println(",,,,,,");
}
}
然后客户端调用
/**
* 一个动态代理就是代理的一个接口,一个动态代理类可以代理多个类
*/
public class me {
public static void main(String[] args) {
host host=new host();
ProxyInvocationHandler p=new ProxyInvocationHandler();
p.setObj(host);
rent proxy=(rent)p.getProxy();
proxy.rent();
}
}
运行结果