代理模式是常用的java设计模式。代理类主要负责为委托类(被代理对象)预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
代理类在执行被代理类的功能方法前后,加入一些业务逻辑:权限的验证,事务的处理,日志的记录。
动态代理的代理类是动态生成的,代理类的字节码将在运行时生成,并载入当前的ClassLoader,如果被代理类实现了接口,可以使用jdk提供的Proxy,InvocationHandler实现。
友情提示
热心小编:ylz2117949797
小余老师刚学习jdk的动态代理的时候,一脸懵逼,这是啥玩意儿啊?为了让大家对jdk的动态代理学起来通俗易懂,小余老师给大家讲一个自己刚毕业找工作时,去中介公司租房子亲身经历的故事。
第一步,咱们先创建一个出租房子的接口Rent。
public interface Rent {
//出租房子
public void rent();
}
第二步,小余老师问你们,是谁要出租房子啊?嗯,当然是房东了,所以咱们要假想一个人,建个类是房东Host ,他要出租房子,实现Rent这个接口。
public class Host implements Rent{
@Override
public void rent() {
System.out.println('我是房东,我要出租房子');
}
}
第三步,咳咳,重点了啊,小余老师要去中介公司了,想要租个房子,去哪个中介公司呢?咱造一个,随便取个名 proInv,但是这个类必须要实现 InvocationHandler,这个是调用处理器接口,自定义invoke方法,用于实现对于真正委托类的代理访问。看下面代码,中介公司里面有个方法,里面有三个参数,小余老师解释下啊,第一个参数proxy是代理对象,就是中介公司里面的小中介,小业务员, 第二个参数是当前调用那个方法,第三个参数是方法的输入参数。有人问我了,里面怎么还有Host host?那小余老师问一句,房东不要去中介公司把房子委托给中介公司嘛!
public class proInv implements InvocationHandler {
Host host; // 房东对象
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
第四步,小余老师去了名叫 proInv这个中介公司,牛逼哄哄地说了一句我要租房子,然后中介公司给我安排了一 位中介。看下面代码,Proxy.newProxyInstance, 这个意思就是说给你动态生成了一个新的代理对象。this.getClass().getClassLoader(),这个是定义代理类的类加载器的意思,你可以理解为这个中介属于中介公司proInv,host.getClass().getInterfaces(),这个是代理类要实现的接口列表的意思,就是要把房子租出去,实现出租房子的接口啊。this ,就是指派方法调用的调用处理程序。
//生成代理对象(中介)
public Object getProxy(){
return Proxy.newProxyInstance(
this.getClass().getClassLoader(),
host.getClass().getInterfaces(),
this
);
}
第五步,公司给我安排了一位中介后,然后就带我看房子,使出了浑身解数,把房子夸上了天,我觉得还不错,就付了钱。看下面代码。
//看房子
public void see(){
System.out.println('我是中介,带小余老师看房子');
}
//收取中介费
public void money(){
System.out.println('我是中介,收小余老师中介费');
}
第六步,房东出租掉房子之前,一般的步骤都是中介先带小余老师看房子,小余老师满意后,接着收取小余老师的租金,但是这个钱是不属于他的,这个行为是属于公司的,所以要在公司proInv里写这个步骤,也就是在公司里的那个invoke方法里面完成这个步骤,看代码。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class proInv implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
see(); // 看房子
Object result = method.invoke(host, args); // 中介真实调用房东的出租房子的能力
money();//收取中介费
return result;
}
//生成代理对象(中介)
public Object getProxy(){
return Proxy.newProxyInstance(
this.getClass().getClassLoader(),//定义代理类的类加载器
host.getClass().getInterfaces(), // 代理类要实现的接口列表
this //指派方法调用的调用处理程序
);
}
//看房子
public void see(){
System.out.println('我是中介,带小余老师看房子');
}
//收取中介费
public void money(){
System.out.println('我是中介,收小余老师中介费');
}
}
第七步,到了这,咱也差不多了,咱们来测试一下,看代码。
public class Test1 {
public static void main(String[] args) {
proInv p = new proInv(); //中介公司
Host h = new Host(); //房东
p.host=h; // 中介公司 与房东建立关联
Rent pro = (Rent) p.getProxy(); // 中介
pro.rent();
}
}
输出的结果为:
我是中介,带小余老师看房子
我是房东,我要出租房子
我是中介,收小余老师中介费
联系客服