代理模式(Proxy Pattern)是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。是一种AOP编程思想。

下面,我们以购买火车票为例,我们可以通过火车站去买票,当一些人不方便时候,可能会通过代售点买票,那么代售点其实可以理解为火车站的代理类,只不过代售点提供了火车站的服务,当然也会收取一定的服务费。
代码如下:
- public class hook {
- /**
- * 售票服务接口
- */
- public interface TicketService {
-
- //售票
- public void sellTicket();
-
- }
-
- /**
- * 售票服务接口实现类,车站
- */
- public static class Station implements TicketService {
-
- @Override
- public void sellTicket() {
- System.out.println("\n\t售票.....\n");
- }
- }
-
- /**
- * 车票代售点
- *
- */
- public static class StationProxy implements TicketService {
-
- private final Station station;
-
- public StationProxy(Station station){
- this.station = station;
- }
-
- @Override
- public void sellTicket() {
-
- // 1.做真正业务前,提示信息
- System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
- // 2.调用真实业务逻辑
- station.sellTicket();
- // 3.后处理 println
- System.out.println("××××欢迎您的光临,再见!××××\n");
- }
- }
-
-
- public static void main(String[] args) {
- Station changchun = new Station();
-
- StationProxy proxy = new StationProxy(changchun);
-
- proxy.sellTicket();
-
- }
-
-
- }
通过以上的代码,还是很容易理解静态代理了,通过代理类去控制实体类的行为,并可以灵活加上之自己的行为~
在Java中,动态代理是通过InvocationHandler接口,重写invoke函数实现的。
还是以火车站售票为例,
代码如下:
- package com.tiancity.dom.lib;
-
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
-
- public class dynamic {
- /**
- * 售票服务接口
- */
- public interface TicketService {
-
- //售票
- public void sellTicket();
-
- }
-
- /**
- * 售票服务接口实现类,车站
- */
- public static class Station implements TicketService {
-
- @Override
- public void sellTicket() {
- System.out.println("\n\t售票.....\n");
- }
- }
-
- /**
- * 车票代售点
- *
- */
- public static class StationProxy implements InvocationHandler {
-
- private final TicketService station;
-
- public StationProxy(TicketService station){
- this.station = station;
- }
-
- //com.sun.proxy.$Proxy0 cannot be cast to
- //getInterfaces 获取的是接口,不是类,所以要用TicketService
- public Object getProxy(){
- return (Object) Proxy.newProxyInstance(this.getClass().getClassLoader(),
- station.getClass().getInterfaces(),this);
- }
-
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- if(method.getName().equals("sellTicket")){
- // 1.做真正业务前,提示信息
- System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
- // 2.调用真实业务逻辑
- result=method.invoke(station, args);
- // 3.后处理 println
- System.out.println("××××欢迎您的光临,再见!××××\n");
- }
- return result;
- }
- }
-
-
- public static void main(String[] args) {
- TicketService dalian = new Station();
-
- StationProxy proxy = new StationProxy(dalian);
-
- TicketService p = (TicketService) proxy.getProxy();
-
- p.sellTicket();
-
- }
-
- }
代理模式可以在不修改真实类代码的情况下,实现对真实类的访问控制、性能优化等功能。Java 中有两种实现代理模式的方法:静态代理和动态代理。静态代理需要在编译之前手动编写代理类,而动态代理可以在运行时动态生成代理类。