设计模式——代理模式
代理模式
代理模式通俗的将就是原来是自己做的事,现在交给别人去做
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强

- 代理类和被代理类需要继承同一个接口,有相同的行为
- 接口中的方法就可以被代理执行
- 用户在通过接口调用方法时,执行的是代理类中实现的方法
- 在代理类的内部,调用了被代理类
- 实际接口的实现是由被代理类实现的
- 代理类可以在原来的基础上扩展
代理又有静态代理和动态代理
静态代理
通过例子来模拟静态代理
模拟一下,委托别人买票的例子
我有1000元,想买一张票,但是自己买不到,委托别人去给我买,但是他需要收取小费才给我买票
首先要有一个共同的买票的行为,就是共同的接口
public interface BuyTicket {
void buy(float money);
}
被代理人真正的实现这个接口
public class BuyTicketImpl implements BuyTicket {
@Override
public void buy(float money) {
System.out.println("购票成功,花费了" + money + "元!");
}
}
代理类通过构造器的方式将被代理类传递进来,并在买票之前收取小费
public class ProxyBuyTicketImpl implements BuyTicket {
private BuyTicketImpl buyTicket;
public ProxyBuyTicketImpl(BuyTicketImpl buyTicket) {
this.buyTicket = buyTicket;
}
@Override
public void buy(float money) {
// 在买票之前需要收100小费
money -= 100;
System.out.println("收取了100的小费!");
// 再真正的执行买票的操作
buyTicket.buy(money);
}
}
@Test
public void test1(){
// 被代理类
BuyTicketImpl buyTicket = new BuyTicketImpl();
// 代理类
ProxyBuyTicketImpl proxyBuyTicket = new ProxyBuyTicketImpl(buyTicket);
proxyBuyTicket.buy(1000);
}

代理类和被代理类应该共同实现一个接口,或者是共同继承某个类
静态代理的类型是事先就确定好的,所以叫做动态代理
基于JDK的动态代理
JDK中提供了一个Proxy类来实现动态代理
该类中提供了一个newProxyInstance返回指定接口的代理类的实例
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h
) throws IllegalArgumentException
loader类加载器来定义代理类interfaces代理类实现的接口列表h调度方法调用的调用处理函数,这个就是代理具体要做的事情
依然是刚才的例子,使用JDK的动态代理来实现
首先要写一个调度方法
public class MyInvocationHandler implements InvocationHandler {
BuyTicketImpl buyTicket;
public MyInvocationHandler(BuyTicketImpl buyTicket) {
this.buyTicket = buyTicket;
}
/**
* 代理执行的具体操作
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("buy".equals(method.getName())){
float money = (float) args[0];
money -= 100;
System.out.println("收了100的小费!");
method.invoke(buyTicket, money);
}
return null;
}
}
创建代理对象
@Test
public void test2(){
// 被代理对象
BuyTicketImpl buyTicket = new BuyTicketImpl();
// 创建代理对象
BuyTicket proxy = (BuyTicket) Proxy.newProxyInstance(
buyTicket.getClass().getClassLoader(),
buyTicket.getClass().getInterfaces(),
new MyInvocationHandler(buyTicket)
);
// 代理执行
proxy.buy(1000);
}
使用JDK的动态代理,我们就可以动态的生成代理,可以很方便的生成多个不同的代理
JDK的动态代理需要有一个代理的接口
基于cglib的动态代理
使用cglib的动态代理需要使用两个包
asm-4.1.jar
cglib-3.1.jar
并且使用cglib动态代理不需要接口就可以实现,可以直接给类创建一个代理对象
比如还是买票的例子
现在我只有类 并没有实现接口
public class BuyTicketImpl{
public void buy(float money) {
System.out.println("购票成功,花费了" + money + "元!");
}
}
使用cglib动态代理
@Test
public void test03(){
// 被代理对象
BuyTicketImpl buyTicket = new BuyTicketImpl();
//创建代理
BuyTicketImpl buyTicketProxy = (BuyTicketImpl)Enhancer.create(buyTicket.getClass(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if ("buy".equals(method.getName())) {
float money = (float) objects[0];
money -= 100;
System.out.println("收了100的小费!");
method.invoke(buyTicket, money);
}
return null;
}
});
buyTicketProxy.buy(1000);
}
使用cglib也需要一个InvocationHandler出来,里面的方法就是具体代理要做的内容

浙公网安备 33010602011771号