【导读】很多场景需要一个中介去完成,例如租房,找工作等。中介会帮你去完成一些其他操作,比如准备合同、与第三方对接等等。此时就需要用到代理模式。
其实Java的动态代理以及spring的CGLib就是用的此模式。
一、定义
为其他对象提供一种代理,以控制对这个对象的访问。比如某些对象的创建比较耗时,就可以使用代理,也可以使用享元模式。
二、实例
有两种方式,一种是静态代理,一种是动态代理。
(1)静态代理
说白了就是在方法执行前后生硬的加上其它处理逻辑。就类似下列代码,在订单保存的前后进行相应的逻辑处理。
public class StaticOrderProxy {
private OrderService orderService;
public StaticOrderProxy(OrderService orderService) {
this.orderService = orderService;
}
public int saveOrder(Order order) {
System.out.println("保存订单之前的处理逻辑");
int orderId = orderService.saveOrder(order);
System.out.println("保存订单之后的处理逻辑");
return orderId;
}
}
静态代理不适合开闭原则,基本没有扩展性。
(2)动态代理
以JDK的动态代理为例,其代理的类是需要继承接口的,否则会报错。
之前专门有一篇【JDK动态代理源码分析】,感兴趣的可以看一下。
1、必须要有一个类实现InvocationHandler接口
public class DynamicOrderProxy implements InvocationHandler {
Object target;
public DynamicOrderProxy(Object target) {
this.target = target;
}
//生成代理类
public Object bind(){
Class<?> aClass = target.getClass();
return Proxy.newProxyInstance(aClass.getClassLoader(),aClass.getInterfaces(),this);
}
/**
* @param proxy 动态代理实例
* @param method 需要执行的方法
* @param args 方法中参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("保存订单之前的逻辑");
Object result = method.invoke(target, args);
System.out.println("保存订单之前的逻辑");
return result;
}
}
2、需要代理的类
1、接口
public interface OrderService {
int saveOrder(Order order);
void test(String a);
}
2、实现类,需要代理的类
public class OrderServiceImpl implements OrderService {
private OrderDao orderDao ;
public OrderServiceImpl() {
}
public OrderServiceImpl(OrderDao orderDao) {
this.orderDao = orderDao;
}
@Override
public int saveOrder(Order order) {
orderDao = new OrderDaoImpl();
return orderDao.saveOrder(order);
}
}
3、测试类
OrderService orderService = (OrderService) new DynamicOrderProxy(new OrderServiceImpl()).bind();
Order order = new Order();
order.setOrderId("测试订单号");
orderService.saveOrder(order);
运行结果:
代理模式比较简单。
三、源码实例
(1)JDK动态代理
(2)Spring的AOP