设计模式之代理模式
一、定义
在Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态代理。在Spring的AOP实现中,主要应用了JDK动态代理以及CGLIB动态代理。
简介
直接来说,代理模式就是为被代理类提供一个外界的访问点。例如火车站售货员替(代理)我们完成在网上购买火车票的动作。
角色
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
二、代码展示
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by yuwu on 2017/9/1.分为静态代理和动态代理,本文先分析静态代理,
后续介绍动态代理。
* 设计模式之代理模式
*/
public class ProxyTest {
public static void main(String[] args) {
//被代理类
Seller seller = new Seller();
//静态代理测试
ProxySell proxySell = new ProxySell(seller);
proxySell.bug();
/**
* 静态代理:
* 1、当【代理接口】扩展时,例如多了【checkout】方法,【商场售货员】需要改代码进行拓展的同时,
* 【ProxySell】也需要改代码进行拓展,导致拓展性差。
* 2、当【被代理类】增加时,例如多了【业务员】等,也需要对代理类【ProxySell】进行扩展,比较繁琐。
*/
//动态代理测试
ProxyDynamic proxyDynamic = new ProxyDynamic(seller);
SellAction sellAction = (SellAction) Proxy.newProxyInstance(proxyDynamic.getClass().getClassLoader(),
seller.getClass().getInterfaces(), proxyDynamic);
sellAction.bug();
/**
* 动态代理:
* 1、拓展灵活,不需要重点关注被代理类的方法, 以及代理类的
* 2、我们不知道要针对哪个接口、哪个被代理类创建代理类,因为它是在运行时被创建的(反射机制)。
*/
}
}
/**
* 代理接口,方法为【bug】
*/
interface SellAction {
void bug();
}
/**
* 商场售货员, 实现购买方法。
*/
class Seller implements SellAction {
@Override
public void bug() {
System.out.println("Bug ticket!");
}
}
/**
* 静态代理类,实现代理动作接口,代理售货员购买。
*/
class ProxySell implements SellAction {
SellAction sellAction;
public ProxySell(SellAction sellAction) {
this.sellAction = sellAction;
}
@Override
public void bug() {
System.out.println("ProxySell : Start");
sellAction.bug();
System.out.println("ProxySell : End");
}
}
/**
* 动态代理类【ProxyDynamic】
* 核心点: 实现【InvocationHandler】接口
*/
class ProxyDynamic implements InvocationHandler {
Object object;
public ProxyDynamic(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("ProxyDynamic : Start");
Object ret = method.invoke(object, args);
System.out.println("ProxyDynamic : End");
return null;
}
}
例子输出:
ProxySell : Start
Bug ticket!
ProxySell : End
ProxyDynamic : Start
Bug ticket!
ProxyDynamic : End