设计模式课程 设计模式精讲 16-2 代理模式Coding-静态代理-1

1    代码演练

1.1  代码演练1(静态代理之分库操作)

1    代码演练
1.1  代码演练1(静态代理之分库操作)

需求:

订单管理,模拟前置后置方法,模拟分库管理

重点:

重点看订单静态代理,动态数据源和分库操作上下文。

UML类图:

订单类:

package com.geely.design.pattern.structural.proxy;

/**
 * 建立订单实体类
 */
public class Order {
    private Object orderInfo;
    //之所以选择integer类型,是为了方便OrderServiceStaticProxy静态代理类进行分库
    private Integer userID;

    public Object getOrderInfo() {
        return orderInfo;
    }

    public void setOrderInfo(Object orderInfo) {
        this.orderInfo = orderInfo;
    }

    public Integer getUserID() {
        return userID;
    }

    public void setUserID(Integer userID) {
        this.userID = userID;
    }
}

订单dao:

package com.geely.design.pattern.structural.proxy;

public interface IOrderDao {
    int insertOrder(Order order);
}

订单daoIMPL:

package com.geely.design.pattern.structural.proxy;

public class OrderDaoImpl implements IOrderDao{
    @Override
    public int insertOrder(Order order) {
        System.out.println("新增一条订单!");
        return 1;
    }
}

订单Service:

package com.geely.design.pattern.structural.proxy;

public interface IOrderService {
    int saveOrder(Order order);
}

订单ServiceIMPL:

package com.geely.design.pattern.structural.proxy;

public class OrderServiceImpl implements IOrderService {
    private IOrderDao orderDao;

    @Override
    public int saveOrder(Order order) {
        //Spring会自己注入,这里我们直接new了
        orderDao = new OrderDaoImpl();
        System.out.println("Service层调用dao层添加Order");
        return orderDao.insertOrder(order);
    }
}

订单静态代理:

package com.geely.design.pattern.structural.proxy.staticProxy;

import com.geely.design.pattern.structural.proxy.IOrderService;
import com.geely.design.pattern.structural.proxy.Order;
import com.geely.design.pattern.structural.proxy.OrderServiceImpl;

public class OrderServiceStaticProxy {
    private IOrderService orderService;

    /**
     * 添加前置方法和后置方法
     * @param order
     * @return
     */
    public int saveOrder(Order order){
        beforeMethod();
        //spring中会注入,这里我new一下
        orderService = new OrderServiceImpl();

        /**
         * 这里添加分库方法,根据user取模,根据余数进行分库
         */
        int userID = order.getUserID();
        int dbRouter = userID%2;//可能分库的实现具体场景是不一样的,这里只是做个简单的模拟
        System.out.println("静态代理分配到 【db"+dbRouter+"】数据库进行处理数据!");
        afterMethod();
        return orderService.saveOrder(order);
    }
    /**
     * 这里参照spring aop的做法,增加了前置通知方法
     */
    private void beforeMethod(){
        System.out.println("静态代理  前置方法");
    }

    /**
     * 这里参照spring aop的做法,增加了后置通知方法
     */
    private void afterMethod(){
        System.out.println("静态代理  后置方法");
    }
}

动态数据源:

package com.geely.design.pattern.structural.proxy.db;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 分库操作:该类为动态数据源类
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDBType();
    }
}

分库操作上下文:

package com.geely.design.pattern.structural.proxy.db;

/**
 * 分库操作:
 * dbRouter上下文类 ,在执行dao层之前,如果我们设置了 setDBType设置了dbType为db1 或者 db0,dao层就会去连接对应的数据库。
 * db0和db1就是Spring容器中我们配置的beanID
 */
public class DataSourceContextHolder {
    //该变量可以存放dataSource的beanName
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>();

    public static void setDBType(String dbType){
        CONTEXT_HOLDER.set(dbType);
    }

    public static void clearDBType(String dbType){
        CONTEXT_HOLDER.remove();
    }

    public static String getDBType(){
        return (String) CONTEXT_HOLDER.get();
    }
}

猜你喜欢

转载自www.cnblogs.com/1446358788-qq/p/11531312.html