代理模式

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 }

 

posted @ 2019-01-06 16:42  逢春  阅读(161)  评论(0编辑  收藏  举报