设计模式--代理模式设计模式 代理
定义:为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介的作用。
类型:结构型
使用场景:(1)保护目标对象,(2)增强目标对象
优点:(1)代理模式能将代理对象与真实被调用的目标对象分离,(2)一定程度上降低了系统的耦合度,扩展性好,(3)保护目标对象,(4)增强目标对象。
缺点:(1)代理模式会造成系统设计中类的数目增加,(2)在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢,(3)怎加了系统的复杂度
扩展:(1)静态代理:在代码中显示指定的代理。(2)动态代理:只能对实现了接口的类代理,并不能针对一个具体的实现类,(在jdk中,动态类无法代理一个类,但是可以代理一个接口),(3)CGLib代理,可以代理类,就是针对类实现代理,这种方法要注意 final 修饰符。
Spring代理选择-扩展:(1)当Bean有实现接口时,Spring就会用JDK的动态代理,(2)当Bean没有实现接口时,Spring使用CGLib,(3)可以强制使用CGLib,(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class = "true"/>)
代理速度对比-扩展:在万次执行的情况下,JDK7和8的动态代理要比CGLib快20%左右。
下面的代码,有涉及到Spring的分库,至于什么是Spring的分库,现在还不知道。
静态代理
// 每个 class 都是一个 .java 文件 public class Order { private Object orderInfo; 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层 public interface IOrderDao { int insert(Order order); } public class OrderDaoImpl implements IOrderDao { @Override public int insert(Order order) { System.out.println("Dao层添加Order成功"); return 1; } } // servece 层 public interface IOrderService { int saveOrder(Order order); } public class OrderServiceImpl implements IOrderService { private IOrderDao iOrderDao; @Override public int saveOrder(Order order) { //Spring会自己注入,我们课程中就直接new了 iOrderDao = new OrderDaoImpl(); System.out.println("Service层调用Dao层添加Order"); return iOrderDao.insert(order); } } // 数据源 public class DataSourceContextHolder { private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>(); public static void setDBType(String dbType){ CONTEXT_HOLDER.set(dbType); } public static String getDBType(){ return (String)CONTEXT_HOLDER.get(); } public static void clearDBType(){ CONTEXT_HOLDER.remove(); } } // 静态代理 public class OrderServiceStaticProxy { private IOrderService iOrderService; public int saveOrder(Order order){ beforeMethod(order); iOrderService = new OrderServiceImpl(); int result = iOrderService.saveOrder(order); afterMethod(); return result; } private void beforeMethod(Order order){ int userId = order.getUserId(); int dbRouter = userId % 2; System.out.println("静态代理分配到【db"+dbRouter+"】处理数据"); //todo 设置dataSource; DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); System.out.println("静态代理 before code"); } private void afterMethod(){ System.out.println("静态代理 after code"); } } // 测试代码 public class Test { public static void main(String[] args) { Order order = new Order(); order.setUserId(2); OrderServiceStaticProxy orderServiceStaticProxy = new OrderServiceStaticProxy(); orderServiceStaticProxy.saveOrder(order); } }UML类图:
动态代理
//这个例子中用到的类都在静态代理的例子中。 // 数据源 public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDBType(); } } // 动态代理: public class OrderServiceDynamicProxy implements InvocationHandler { private Object target; public OrderServiceDynamicProxy(Object target) { this.target = target; } public Object bind(){ Class cls = target.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this); } @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){ 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+"】处理数据"); //todo 设置dataSource; DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); } private void afterMethod(){ System.out.println("动态代理 after code"); } } // 测试类 public class Test { public static void main(String[] args) { Order order = new Order(); // order.setUserId(2); order.setUserId(1); IOrderService orderServiceDynamicProxy = (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind(); orderServiceDynamicProxy.saveOrder(order); } }源码示例
jdk中的 java.lang.reflect.proxy 类。
Spring 中的 ProxyFactoryBean 类,这个类的核心方法就是 getObject()方法。 或是是Spring 中 JdkDynamicAopProxy 类,也是Spring重要的类。 CglibAopProxy类。
mybatis 中的 MapperProxyFactory 类。