代理模式
Posted linbq1911
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式相关的知识,希望对你有一定的参考价值。
1.定义:为其他对象提供一种代理,以控制对这个对象的访问;
代理对象在客户端和目标对象之间起到中介的作用。
2.类型:结构型
3.适用场景:保护目标对象;增强目标对象。
4.优点:代理模式能将代理对象与真实被调用的目标对象分离;
一定程度上降低了系统的耦合度,扩展性好;
保护目标对象;增强目标对象。
5.缺点:代理模式会造成系统设计中类的数目增加;在客户端和目标对象增加一个代理对象,
会造成请求处理速度变慢;增加系统的复杂度。
6.扩展:静态代理、动态代理、CGLib代理,Spring代理选择,当Bean有实现接口时,
Spring就会用JDK的动态代理,当Bean没有实现接口时,Spring使用CGLib;
可以强制使用CGLib,在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>。
7.相关设计模式:装饰者模式、适配器模式。
8.实例目录package
9.实例UML类图
10.代码
1 package com.geely.design.pattern.structural.proxy; 2 3 public class Order { 4 private Object orderInfo; 5 private Integer userId; 6 7 public Object getOrderInfo() { 8 return orderInfo; 9 } 10 11 public void setOrderInfo(Object orderInfo) { 12 this.orderInfo = orderInfo; 13 } 14 15 public Integer getUserId() { 16 return userId; 17 } 18 19 public void setUserId(Integer userId) { 20 this.userId = userId; 21 } 22 }
1 package com.geely.design.pattern.structural.proxy; 2 3 public interface IOrderDao { 4 int insertOrder(Order order); 5 }
1 package com.geely.design.pattern.structural.proxy; 2 3 public class OrderDaoImpl implements IOrderDao { 4 @Override 5 public int insertOrder(Order order) { 6 System.out.println("Dao层添加Order成功"); 7 return 1; 8 } 9 }
1 package com.geely.design.pattern.structural.proxy; 2 3 public interface IOrderService { 4 int saveOrder(Order order); 5 }
1 package com.geely.design.pattern.structural.proxy; 2 3 public class OrderServiceImpl implements IOrderService { 4 private IOrderDao iOrderDao; 5 @Override 6 public int saveOrder(Order order) { 7 iOrderDao = new OrderDaoImpl(); 8 System.out.println("Service层调用Dao层添加Order"); 9 return iOrderDao.insertOrder(order); 10 } 11 }
1 package com.geely.design.pattern.structural.proxy.db; 2 3 public class DataSourceContextHolder { 4 private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); 5 public static void setDBType(String dbType){ 6 CONTEXT_HOLDER.set(dbType); 7 } 8 9 public static String getDBType(){ 10 return CONTEXT_HOLDER.get(); 11 } 12 13 public static void clearDBType(){ 14 CONTEXT_HOLDER.remove(); 15 } 16 }
1 package com.geely.design.pattern.structural.proxy.db; 2 3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 5 public class DynamicDataSource extends AbstractRoutingDataSource { 6 @Override 7 protected Object determineCurrentLookupKey() { 8 return DataSourceContextHolder.getDBType(); 9 } 10 }
静态代理
1 package com.geely.design.pattern.structural.proxy.staticproxy; 2 3 import com.geely.design.pattern.structural.proxy.IOrderService; 4 import com.geely.design.pattern.structural.proxy.Order; 5 import com.geely.design.pattern.structural.proxy.OrderServiceImpl; 6 import com.geely.design.pattern.structural.proxy.db.DataSourceContextHolder; 7 8 public class OrderServiceStaticProxy { 9 private IOrderService iOrderService; 10 11 public int saveOrder(Order order){ 12 beforeMethod(order); 13 iOrderService = new OrderServiceImpl(); 14 int result = iOrderService.saveOrder(order); 15 afterMethod(); 16 return result; 17 } 18 19 private void beforeMethod(Order order){ 20 int userId = order.getUserId(); 21 int dbRouter = userId % 2; 22 System.out.println("静态代理分配到【db"+dbRouter+"】处理数据"); 23 //todo 设置dataSource; 24 DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); 25 System.out.println("静态代理 before code"); 26 } 27 private void afterMethod(){ 28 System.out.println("静态代理 after code"); 29 } 30 }
1 package com.geely.design.pattern.structural.proxy.staticproxy; 2 3 import com.geely.design.pattern.structural.proxy.Order; 4 5 public class Test { 6 public static void main(String[] args){ 7 Order order = new Order(); 8 order.setUserId(1); 9 OrderServiceStaticProxy orderServiceStaticProxy = new OrderServiceStaticProxy(); 10 orderServiceStaticProxy.saveOrder(order); 11 } 12 }
动态代理
1 package com.geely.design.pattern.structural.proxy.dynamicproxy; 2 3 import com.geely.design.pattern.structural.proxy.Order; 4 import com.geely.design.pattern.structural.proxy.db.DataSourceContextHolder; 5 6 import java.lang.reflect.InvocationHandler; 7 import java.lang.reflect.Method; 8 import java.lang.reflect.Proxy; 9 10 public class OrderServiceDynamicProxy implements InvocationHandler { 11 12 private Object target; 13 14 public OrderServiceDynamicProxy(Object target){ 15 this.target = target; 16 } 17 18 public Object bind(){ 19 Class clazz = target.getClass(); 20 return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this); 21 } 22 @Override 23 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 24 Object argObject = args[0]; 25 beforeMethod(argObject); 26 Object object = method.invoke(target,args); 27 afterMethod(); 28 return object; 29 } 30 31 private void beforeMethod(Object obj){ 32 int userId = 0; 33 System.out.println("动态代理 before code"); 34 if(obj instanceof Order){ 35 Order order = (Order)obj; 36 userId = order.getUserId(); 37 } 38 int dbRouter = userId % 2; 39 System.out.println("动态代理分配到【db"+dbRouter+"】处理数据"); 40 //todo 设置dataSource; 41 DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); 42 } 43 44 private void afterMethod(){ 45 System.out.println("动态代理 after code"); 46 } 47 }
1 package com.geely.design.pattern.structural.proxy.dynamicproxy; 2 3 import com.geely.design.pattern.structural.proxy.IOrderService; 4 import com.geely.design.pattern.structural.proxy.Order; 5 import com.geely.design.pattern.structural.proxy.OrderServiceImpl; 6 7 public class Test { 8 public static void main(String[] args) { 9 Order order = new Order(); 10 order.setUserId(2); 11 IOrderService orderServiceDynamicProxy = (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind(); 12 orderServiceDynamicProxy.saveOrder(order); 13 } 14 }
以上是关于代理模式的主要内容,如果未能解决你的问题,请参考以下文章