zoukankan      html  css  js  c++  java
  • 代理模式-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();
            }
        }

      运行结果如下:

    本文来自博客园,作者:l-coil,转载请注明原文链接:https://www.cnblogs.com/l-coil/p/12864833.html

  • 相关阅读:
    软件测试从业者,试用期生存指南(完整版)
    学测试,看视频?NONONO,除非这种情况
    vi / vim 字符替换详解
    Centos 下 mysql 安装过程
    Web测试到底是在测什么(资料合集)
    我花了两个小时,写了这份年终总结 。
    拒绝无效加班 !
    你离月薪30K还差哪些?
    从业十年分享:你应该知道的一些测试职业事实!
    别再TM跟我说找不到满意的工作!
  • 原文地址:https://www.cnblogs.com/xianquan/p/12864833.html
Copyright © 2011-2022 走看看