23种设计模式之代理模式

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 实例。
  • 客户端通过代理对象调用方法,这些方法调用会被转发到 InvocationHandlerinvoke 方法中进行处理。

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. 总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值