你要买一个二手房,你要是自己找房源、谈判、过户的话,这一套程序太麻烦。往往你会找一个房屋中介,中介帮你找房源、帮你谈判、帮你跑过户手续。
在这个过程中你就是“委托人”,这个房屋中介就是“代理人”,你只需要找到房屋中介把你的购房需求、相关材料、身份证等给他,他就可以帮你完成后续过程,你不用跑来跑去
。
而且,中介在帮你干完正事(指买房)之后往往还能干一些别的事情(和买房无关的其他事情),比如把你的个人信息卖给了其它人(信息泄露目前很普遍)。
买房业务
public interface IBuyHouse {
public void buyHouse();
}
委托人委托
public class HouseDelegation implements IBuyHouse {
@Override
public void buyHouse() {
System.out.println("找房源");
System.out.println("谈价钱");
System.out.println("买房");
}
}
委托人找代理人代替买房
在代理类中定义了一个IBuyHouse类型的变量,可以这么理解,虚位以待等着委托人上门。
public class HouseAgent implements IBuyHouse {
private IBuyHouse iBuyHouse;
public HouseAgent(IBuyHouse iBuyHouse) {
this.iBuyHouse = iBuyHouse;
}
@Override
public void buyHouse() {
System.out.println("先付5000");
iBuyHouse.buyHouse();
System.out.println("卖掉信息");
}
}
测试*
public class Test {
public static void main(String[] args) {
HouseDelegation houseDelegation = new HouseDelegation();
HouseAgent houseAgent = new HouseAgent(houseDelegation);
houseAgent.buyHouse();
}
}
运行结果:
先付5000
找房源
谈价钱
买房
卖掉信息
总结:Java中使用代理技术主要用于扩展原功能又不侵入(修改)源代码。
上面这种由程序员创建代理类,即在程序运行前代理类的.class文件就已经存在了的形式叫做静态代理
缺点:代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多。而且一旦接口增加方法,目标对象与代理对象都要维护。
静态代理和动态代理的区别:静态代理每增加一个业务都需要new一个代理类
那怎么办呢,动态代理出场 ===>
通过动态代理技术:最重要的是拿到一个代理对象,这个代理对象可以有相比于原来的业务增强逻辑
动态代理:使用动态代理,我们最大的改变就是不需要定义一个个的代理类了。最重要的是获取到代理对象,有了代理对象,我们就可以直接调用代理对象了,只需要我们传入相关信息,它就可以返回我们需要的代理对象
Object obj = Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
obj就是我们要得到的代理对象
需要传入的三个参数
ClassLoader:这是一个类加载器,是java虚拟机底层的玩意,固定的写法,如下:
当前类名.class.getClassLoader()或者 委托类对象.getClass().getClassLoader()
interfaces:是一个数组,因为代理类也是类,类是可以实现多个接口的,你想让这个代理对象实现什么接口你就传入即可,也正因为有接口这个参数,所以使用JDK动态代理必须有接口存在
比如new Class[]{IBuyCar.class,IBuyHouse.class} 或者委托类对象.getClass().getInterfaces()
InvocationHandler:这个参数是帮我们增强业务逻辑的,也就是说增加额外功能的,你在interfaces中指定的所有接口的接口方法都可以在这里针对性的增强,InvocationHandler是一个接口,我们需要实现在这里实现这个接口,在实现类中写我们增强逻辑