动态代理实现分库

This commit is contained in:
2020-03-03 15:58:45 +08:00
parent f42cb473cb
commit d8e80f07b0
2 changed files with 110 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
package top.fjy8018.designpattern.pattern.structural.proxy.dynamic;
import lombok.extern.slf4j.Slf4j;
import top.fjy8018.designpattern.pattern.structural.proxy.Order;
import top.fjy8018.designpattern.pattern.structural.proxy.db.DataSourceContextHolder;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理实现分库
* 动态代理适用场景更加广泛,可以实现通用分库逻辑
*
* @author F嘉阳
* @date 2020/3/3 11:00
*/
@Slf4j
public class OrderServiceDynamicProxy implements InvocationHandler {
private Object target;
private static final String DB = "db";
public OrderServiceDynamicProxy(Object target) {
this.target = target;
}
/**
* 绑定目标对象
*
* @return
*/
public Object bind() {
Class clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
/**
* 代理
*
* @param proxy 代理对象,一般不调用该参数
* @param method 要被增强的方法对象
* @param args 方法参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 参数传递
Object argObject = args[0];
beforeMethod(argObject);
// object是要被增强的方法的返回值
Object object = method.invoke(target, args);
afterMethod();
return object;
}
/**
* 前置增强方法
*
* @param args 方法参数
*/
private void beforeMethod(Object args) {
int userId = 0;
// 对参数取模
log.info("动态代理before code");
if (args instanceof Order) {
Order order = (Order) args;
userId = order.getUserId();
}
int dbRouter = userId % 2;
log.info("动态代理分配到【db{}】处理数据", dbRouter);
// 设置DataSource
DataSourceContextHolder.setDBType(DB + dbRouter);
}
private void afterMethod() {
log.info("动态代理after code");
}
}

View File

@@ -0,0 +1,28 @@
package top.fjy8018.designpattern.pattern.structural.proxy.dynamic;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import top.fjy8018.designpattern.pattern.structural.proxy.IOrderService;
import top.fjy8018.designpattern.pattern.structural.proxy.IOrderServiceImpl;
import top.fjy8018.designpattern.pattern.structural.proxy.Order;
/**
* @author F嘉阳
* @date 2020/3/3 15:54
*/
@Slf4j
class OrderServiceDynamicProxyTest {
@Test
void invoke() {
Order order1 = new Order();
order1.setUserId(1);
Order order2 = new Order();
order2.setUserId(2);
// 动态代理直接代理接口
IOrderService proxy = (IOrderService) new OrderServiceDynamicProxy(new IOrderServiceImpl()).bind();
proxy.save(order1);
proxy.save(order2);
}
}