文章目录
1. 简介
代理模式为其他对象提供一种代理,以控制对这个对象的访问。
其实就是相当于有一个替身,让他来做事情,但是这个替身可以做的更多。
2. 静态代理
静态代理是指在编译时期就确定了代理类和被代理类的关系。代理类和被代理类都需要实现相同的接口或者继承相同的抽象类,代理类通过持有被代理类的实例,在调用方法时对其进行增强或控制访问。
一般流程:
- 客户端创建代理对象,并且将真实对象传递给代理对象(通常是通过代理对象的构造函数)。
- 客户端调用代理对象的方法。
- 代理对象在执行方法前,先进行一些前置操作,如权限检查、参数验证等。
- 代理对象调用真实对象的相应方法,将方法的执行结果返回给客户端。
- 代理对象在执行方法后,可能会进行一些后置操作,如记录日志、释放资源等。
2.1 Order
public class Order {
private String info;
private String userId;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
@Override
public String toString() {
return "Order{" +
"info='" + info + '\'' +
", userId='" + userId + '\'' +
'}';
}
}
2.2 OrderDao
public interface OrderDao {
int insert(Order order);
}
2.3 OrderService
public interface OrderService {
int saveOrder(Order order);
}
2.4 OrderDaoImpl
public class OrderDaoImpl implements OrderDao{
@Override
public int insert(Order order) {
System.out.println("持久层。。保存订单信息");
return 1;
}
}
2.5 OrderServiceImpl
public class OrderServiceImpl implements OrderService{
private OrderDao orderDao;
public OrderServiceImpl() {
this.orderDao = new OrderDaoImpl();
}
public int saveOrder(Order order) {
System.out.println("静态代理开始做业务,调用持久层...");
return orderDao.insert(order);
}
}
2.6 OrderServiceImplStaticProxy
/*
* 代理对象
* */
public class OrderServiceImplStaticProxy {
private OrderService orderService;
// 对其进行了增强
public int saveOrder(Order order){
orderService = new OrderServiceImpl();
// 执行代理的业务逻辑
// 开启事务
before();
System.out.println("静态代理开始......执行业务层等...");
int i = orderService.saveOrder(order);
// 提交事务
after();
return i;
}
public void after(){
System.out.println("静态代理提交事务......");
}
public void before(){
System.out.println("静态代理开启事务......");
}
}
2.7 Test
public class Test {
public static void main(String[] args) {
Order order = new Order();
order.setUserId("1");
order.setInfo("购买HuaWei");
OrderServiceImplStaticProxy proxy = new OrderServiceImplStaticProxy();
proxy.saveOrder(order);
}
}
2.8 运行结果
静态代理开启事务......
静态代理开始......执行业务层等...
静态代理开始做业务,调用持久层...
持久层。。保存订单信息
静态代理提交事务......
3. 动态代理
其他类与静态代理一样
动态代理是一种在运行时动态地创建代理对象的代理模式。与静态代理不同,动态代理不需要在编译时就定义好代理类,而是在程序运行过程中,根据需要动态地生成代理类及其对象。它可以代理多个不同类型的对象,并且能够灵活地处理方法调用,为被代理对象的方法调用添加统一的前置或后置操作。
实现机制
- 动态代理主要依赖于反射机制来实现。在 Java 中,常用的动态代理有两种方式:基于 JDK 的动态代理和基于 CGLIB 的动态代理。
工作流程(以 JDK 动态代理为例)
- 定义一个接口和实现该接口的真实类,这个真实类包含了实际的业务逻辑。
- 实现
InvocationHandler
接口,在invoke
方法中定义代理逻辑。这个方法会在代理对象的方法被调用时执行,在其中可以进行前置操作(如权限检查、参数验证等),调用真实对象的方法,以及进行后置操作(如记录日志、返回结果处理等)。 - 使用
Proxy
类的newProxyInstance
方法创建代理对象,传入类加载器、真实对象实现的接口数组和InvocationHandler
实例。 - 客户端通过代理对象调用方法,这些方法调用会被转发到
InvocationHandler
的invoke
方法中进行处理。
3.1 OrderServiceImplDynamicProxy
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 代理对象
* */
public class OrderServiceImplDynamicProxy implements InvocationHandler {
private Object service;
// 对其进行了增强
public OrderServiceImplDynamicProxy(Object service) {
this.service = service;
}
public Object bind(){
return Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(),this);
}
public void after(){
System.out.println("动态代理提交事务......");
}
public void before(){
System.out.println("动态代理开启事务......");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(service,args);
after();
return invoke;
}
}
3.2 Test
public class Test {
public static void main(String[] args) {
OrderService orderService = (OrderService) new OrderServiceImplDynamicProxy(new OrderServiceImpl()).bind();
Order order = new Order();
order.setUserId("1001");
order.setInfo("购买华为Meta70");
orderService.saveOrder(order);
}
}
3.3 运行结果
动态代理开启事务......
动态代理开始做业务,调用持久层...
持久层。。保存订单信息
动态代理提交事务......
4. 总结
无