设计模式:代理模式
DK的动态代理
JDK的动态代理是依据目标类的接口实现的,目标类实现接口的所有方法都会被动态代理增强
就是可以在目标类的目标方法的前后添加方法,就是AOP的实现
import java.lang.reflect.Proxy;
最核心的一句
Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),InvocationHandler h);
其中:
cls.getClassLoader() = 目标类的类加载器
cls.getInterfaces() = 目标类实现的接口
InvocationHandler h = InvocationHandler接口的具体实现对象
具体实现:DAO层就不写了
目标类接口:
package com.edward.design.pattern.structural.proxy; /** * Created by Edward on 2018/12/12. */ public interface IOrderService { int saveOrder(Order order); int saveOrder2(Order order); }
目标类:
package com.edward.design.pattern.structural.proxy; /** * Created by Edward on 2018/12/12. */ public class OrderServiceImpl implements IOrderService { private IOrderDAO iOrderDAO; @Override public int saveOrder(Order order) { iOrderDAO = new OrderDAOImpl(); System.out.println("Service层调用Dao层添加Order"); return iOrderDAO.insert(order); } @Override public int saveOrder2(Order order) { iOrderDAO = new OrderDAOImpl(); System.out.println("Service层再次调用Dao层添加Order"); return iOrderDAO.insert(order); } }
代理类:
package com.edward.design.pattern.structural.proxy.dynamicproxy; import com.edward.design.pattern.structural.proxy.Order; import com.edward.design.pattern.structural.proxy.db.DataSourceContextHolder; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by edward */ public class OrderServiceDynamicProxy implements InvocationHandler { private Object target; public OrderServiceDynamicProxy(Object target) { this.target = target; } public Object bind(){ Class cls = target.getClass(); // 该类实现了InvocationHandler接口,并重写了invoke方法,所以可将该类的对象传入到第三个参数中 return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this); } @Override // proxy:代理对象的引用 method:目标方法 args:目标方法参数 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){ int userId = 0; System.out.println("动态代理 before code"); if(obj instanceof Order){ Order order = (Order)obj; userId = order.getUserId(); } int dbRouter = userId % 2; System.out.println("动态代理分配到【db"+dbRouter+"】处理数据"); } private void afterMethod(){ System.out.println("动态代理 after code"); } }
测试类:
package com.edward.design.pattern.structural.proxy.dynamicproxy; import com.edward.design.pattern.structural.proxy.IOrderService; import com.edward.design.pattern.structural.proxy.Order; import com.edward.design.pattern.structural.proxy.OrderServiceImpl; /** * Created byedward */ public class Test { public static void main(String[] args) { Order order = new Order(); order.setUserId(1); IOrderService orderServiceDynamicProxy = (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind(); orderServiceDynamicProxy.saveOrder(order); orderServiceDynamicProxy.saveOrder2(order); } }
测试结果:
动态代理 before code
动态代理分配到【db0】处理数据
Service层调用Dao层添加Order
Dao层添加Order成功
动态代理 after code
动态代理 before code
动态代理分配到【db0】处理数据
Service层再次调用Dao层添加Order
Dao层添加Order成功
动态代理 after code