代理模式
定义:由于某些原因需要给某对象提供一个代理以控制该对象的访问
结构:
- 抽象主题(Subject): 接口声明要实现的业务方法
- 真实主题 (Real Subject): 实现抽象主题里的业务方法
- 代理类(Proxy):提供了与真实主题相同的接口,它可以扩展、控制真实主题的功能。
代理模式的结构很简单,是通过继承抽象主题的代理类来包含真实主题,从而来实现对真实主题的访问。
代码示例:
public interface Ticket {
void buyTicket();
}
public class OfficialTicket implements Ticket {
@Override
public void buyTicket() {
System.out.println("官方途径购票");
}
}
public class ProxyTicket implements Ticket {
private OfficialTicket officialTicket=new OfficialTicket();
@Override
public void buyTicket() {
System.out.println("我把钱给了去哪网,委托购票");
officialTicket.buyTicket();
}
}
测试代码:
public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
ProxyTicket proxyTicket = new ProxyTicket();
proxyTicket.buyTicket();
以上就是代理模式的实现,也可以说是静态代理
静态代理的局限性:
- 如果我们需要再增加一个需要代理的方法,那我们需要修改上面3个类,每个类都要加对应的逻辑。
- 如果我们想再代理一个其他的对象,也需要对代理类进行修改。
那么如果用动态代理实现上面的代码会怎么样呢?
Ticket类和OfficialTicket不变
public class TicketInvocationHandler implements InvocationHandler {
private Ticket ticket;
public TicketInvocationHandler(Ticket ticket) {
this.ticket = ticket;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我把钱给了去哪网,委托购票");
method.invoke(ticket,args);
return null;
}
}
测试代码:
public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
Ticket ticket = new OfficialTicket();
//将操作者对象进行注入
TicketInvocationHandler handler = new TicketInvocationHandler(ticket);
//生成代理对象
Ticket operationProxy = (Ticket) Proxy.newProxyInstance(ticket.getClass().getClassLoader(),
ticket.getClass().getInterfaces(), handler);
operationProxy.buyTicket();
}
此时如果我们想增加一个退票方法,如果用动态代理,那么只需要改动Ticket类和OfficialTicket类。
Cglib实现:
public class TicketMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("我把钱给了去哪网,委托购票");
Object object = proxy.invokeSuper(obj, args);
return object;
}
}
测试代码:
public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
Enhancer enhancer = new Enhancer();
// 设置enhancer对象的父类
enhancer.setSuperclass(OfficialTicket.class);
// 设置enhancer的回调对象
enhancer.setCallback(new TicketMethodInterceptor());
// 创建代理对象
Ticket proxy= (Ticket)enhancer.create();
// 通过代理对象调用目标方法
proxy.buyTicket();
}