一个代理类去代理另一个真实类,同时代理类去做一些扩展的功能(不去直接操作直接类),例如
现实生活中的房屋中介、婚介所等等。
1静态代理 :由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了
2动态代理 在程序运行时通过反射机制动态创建的
抽象角色:一般会使用接口或者抽象类来解决。
真实角色:被代理的角色。
代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作。
客户:访问代理对象的人。
静态代理
静态代理的案例
抽象角色
public interface Rent {
public void rent();
}
真实角色
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要租房子");
}
}
代理角色
public class Agent implements Rent {
public Host host;
//中介代理房东的权利去租房子
public void rent() {
seeHouse();
signContract();
host.rent();
}
public Agent(Host host){
this.host=host;
}
public Agent(){
}
//看房子
public void seeHouse(){
System.out.println("中介带租客去看房子");
}
//签合同
public void signContract(){
System.out.println("中介和租客签合同");
}
}
客户
public class Tenant {
public static void main(String[] args) {
//想租房子先得有个房东
Host host =new Host();
//中介代理了房东
Agent agent=new Agent(host);
//通过中介去租房子
agent.rent();
}
}
可以使真实角色的操作更加纯粹,不用去关注一些公关的业务
公共部分交给代理角色,代理角色实现业务的分工
公共业务发生扩展时,方便集中管理
一个真实角色就会产生一个代理角色,代码量翻倍开发效率低,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是直接写好的
动态代理分为两个大类:
基于接口的动态代理
JDK动态代理
基于类的动态代理
基于类 cglib
java字节码实现 javaSist
实现接口 InvocationHandler 去重写 Invoke ( )方法
Proxy类 静态方法 调用程序处理角色 来处理要调用的接口对象
动态代理的实现
1 类的封装
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;
}
}
2 封装类的使用
public class test {
public static void main(String[] args) {
//真实角色
Host host=new Host();
//代理角色 动态类
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置要代理生成的类
pih.setTarget(host);
//动态生成代理类
//注意 一定要写成接口类才行 否则报错
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
因为是在ProxyInvocationHandler里面的Proxy.newProxyInstance()实现的是一个接口 所以得到的也应该是接口类 不能写具体类
可以使真实角色的操作更加纯粹,不用去关注一些公关的业务
公共部分交给代理角色,代理角色实现业务的分工
公共业务发生扩展时,方便集中管理
一个动态代理类代理的是一个接口,一般对应的一类业务
一个动态代理类可以代理多个类 ,只要是实现了同一个接口即可
Spring里面的AOP实现就是采用了代理模式
1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。