打赏
Fork me on GitHub

代理模式-1(静态代理)

代理模式应用场景:

  生活中的租房中介、售票黄牛、婚介、经纪人、快递、事物代理、非侵入式日志监听等,都属于是代理模式的实际体现、代理模式(proxy Pattern)的定义也非常简单,是指为其他对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间祈祷中介作用,代理式属于结构型设计模式。使用代理主要由两个目的:一是保护目标对象,二是增强目标对象。

静态代理

  在分布式业务场景中,通常会对数据库进行分库分表,分库分表之后使用 Java 操作时就可能需要配置多个数据源,我们通过设置数据源路由来动态切换数据源。先创建 Order 订单类:

@Data
public class Order {
    private Object orderInfo;
    private Long createTime;
    private String id;
}

  创建OrderDao 持久层操作类:

public class OrderDao {
    public int insert(Order order){
        System.out.println("OrderDao 创建 order 成功!");
        return 1;
    }
}

  创建 IOrderService 接口:

public class OrderService implements IOrderService {
    private OrderDao orderDao;

    public OrderService(){
        //如果使用spring是自动注入的
        //为了使用方便,在构造方法中将orderDao直接初始化
        orderDao = new OrderDao();
    }
    @Override
    public int createOrder(Order order) {
        System.out.println("OrderService 调用 OrderDao 闯将订单");
        return orderDao.insert(order);
    }
}

  接下来使用动态代理,主要完成的功能时:根据订单创建时间自动按年份进行分库。根据开闭原则,修改原来写好的代码逻辑,通过代理对象来完成。先创建数据源路由对象,使用 ThreadLocal 的单例事项 DynamicDataSourceEntry 类:

package com.xq.design.proxy.staticproxy.dbroute.db;
//动态切换数据源
public class DynamicDataSourceEntry {
    //默认数据源
    public final static String DEFAULT_SOURCE = null;

    private  final static ThreadLocal<String> local = new ThreadLocal<String>();
    private DynamicDataSourceEntry(){}

    //清空数据源
    public static void clear(){
        local.remove();
    }
    //获取当前正在使用的数据源名字
    public static String get(){
        return local.get();
    }
    //还原当前切换的数据源
    public static void restore(){
        local.set(DEFAULT_SOURCE);
    }
    //设置已知名字的数据源
    public static void set(String source){
        local.set(source);
    }
    //根据年份动态设置数据源
    public static void set(int year){
        local.set("DB_" + year);
    }
}
DynamicDataSourceEntry

  创建切换数据源的代理类 OrderServiceStaticProxy:

package com.xq.design.proxy.staticproxy.dbroute.proxy;

import com.xq.design.proxy.staticproxy.IOrderService;
import com.xq.design.proxy.staticproxy.Order;
import com.xq.design.proxy.staticproxy.dbroute.db.DynamicDataSourceEntry;

import java.text.SimpleDateFormat;
import java.util.Date;

public class OrderServiceStaticProxy implements IOrderService {

    private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
    private IOrderService orderService;
    public OrderServiceStaticProxy(IOrderService orderService){
        this.orderService = orderService;
    }

    @Override
    public int createOrder(Order order) {
        before();
        Long time = order.getCreateTime();
        Integer dbRouter = Integer.valueOf(yearFormat.format(new Date(time)));
        System.out.println("静态代理类自动分配到【DB_" + dbRouter + "】数据源处理数据");
        DynamicDataSourceEntry.set(dbRouter);
        orderService.createOrder(order);
        after();
        return 0;
    }
    private void before(){
        System.out.println("Proxy before method.");
    }
    private void after(){
        System.out.println("Proxy after method.");
    }
}
OrderServiceStaticProxy

   测试代码如下:

    @Test
    void test(){
        try{
            Order order = new Order();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            Date date = sdf.parse("2020/05/10");
            order.setCreateTime(date.getTime());
            IOrderService orderService = new OrderServiceStaticProxy(new OrderService());
            orderService.createOrder(order);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

  运行结果如下:

posted @ 2020-05-10 22:17  l-coil  阅读(195)  评论(0编辑  收藏  举报