动态代理示例实现动态分库功能示例
1、代码结构如下图:
2、创建订单和用户类
package com.rf.designPatterns.structural.proxy;
/**
* @description: 订单和用户类
* @author: xz
*/
public class Order {
private Object orderId;//订单id
private Integer userId;//用户id
public Object getOrderId() {
return orderId;
}
public void setOrderId(Object orderId) {
this.orderId = orderId;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
3、创建Service层
package com.rf.designPatterns.structural.proxy;
/**
* @description: Service层
* @author: xz
*/
public interface OrderService {
int saveOrder(Order order);
}
4、创建Dao层
package com.rf.designPatterns.structural.proxy;
/**
* @description: Dao层
* @author: xz
*/
public interface OrderDao {
int insert(Order order);
}
5、创建Dao实现层
package com.rf.designPatterns.structural.proxy;
/**
* @description: Dao实现层
* @author: xz
*/
public class OrderDaoImpl implements OrderDao{
@Override
public int insert(Order order) {
System.out.println("Dao层添加订单成功");
return 1;
}
}
6、创建Service实现层
package com.rf.designPatterns.structural.proxy;
/**
* @description: Service实现层
* @author: xz
*/
public class OrderServiceImpl implements OrderService{
private OrderDao orderDao;
@Override
public int saveOrder(Order order) {
//spring会自动注入,这里我们自己直接new
orderDao=new OrderDaoImpl();
System.out.println("Service调用Dao层的inser方法添加订单");
orderDao.insert(order);
return 1;
}
}
7、创建数据源上下文类
package com.rf.designPatterns.structural.proxy.db;
/**
* @description: 数据源上下文类
* @author: xz
*/
public class DataSourceContextHolder {
private static final ThreadLocal CONTEXT_HOLDER=new ThreadLocal();
public static void setDBType(String dbType){
CONTEXT_HOLDER.set(dbType);
}
public static String getDBType(){
return CONTEXT_HOLDER.get();
}
public static void clearDBType(){
CONTEXT_HOLDER.remove();
}
}
8、创建动态的数据源类
package com.rf.designPatterns.structural.proxy.db;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @description: 动态的数据源类
* @author: xz
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDBType();
}
}
9、创建Service层的动态代理
package com.rf.designPatterns.structural.proxy.dynamicProxy;
import com.rf.designPatterns.structural.proxy.Order;
import com.rf.designPatterns.structural.proxy.db.DataSourceContextHolder;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @description: Service层的动态代理
* @author: xz
*/
public class OrderServiceDynamicProxy implements InvocationHandler {
//声明一个目标对象
private Object target;
//通过构造器添加目标对象
public OrderServiceDynamicProxy(Object target) {
this.target = target;
}
//绑定目标对象
public Object bind(){
Class cls=target.getClass();//获取目标类的class对象
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this);
}
/**
* @param proxy 动态生成的代理类
* @param method 要被增强的方法对象
* @param args method方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object argObject = args[0];
beforeMethod(argObject);
Object object = method.invoke(target, args);
afterMethod();
return object;
}
private void beforeMethod(Object obj){
System.out.println("动态代理before代码, 在invoke方法之前执行");
int userId=0;
if(obj instanceof Order){
Order order=(Order)obj;
userId= order.getUserId();
}
int dbRouter=userId % 2;
System.out.println("动态代理分配到 db【" +dbRouter+ "】 数据库处理数据");
DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter));
}
private void afterMethod(){
System.out.println("动态代理after代码, 在invoke方法之后执行");
}
}
10、创建测试类
package com.rf.designPatterns.structural.proxy.dynamicProxy;
import com.rf.designPatterns.structural.proxy.Order;
import com.rf.designPatterns.structural.proxy.OrderService;
import com.rf.designPatterns.structural.proxy.OrderServiceImpl;
public class Test {
public static void main(String[] args) {
Order order=new Order();
//order.setUserId(1);
order.setUserId(2);
OrderService orderServiceDynamicProxy = (OrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind();
orderServiceDynamicProxy.saveOrder(order);
}
}
11、测试结果如下图: