diff --git a/src/main/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxy.java b/src/main/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxy.java new file mode 100644 index 0000000..31a65a3 --- /dev/null +++ b/src/main/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxy.java @@ -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"); + } +} diff --git a/src/test/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxyTest.java b/src/test/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxyTest.java new file mode 100644 index 0000000..ce08296 --- /dev/null +++ b/src/test/java/top/fjy8018/designpattern/pattern/structural/proxy/dynamic/OrderServiceDynamicProxyTest.java @@ -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); + } +} \ No newline at end of file