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(); } }