设计模式之代理模式

一,定义与类型

定义:为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介作用
类型:结构型

二,适用场景

1.保护目标对象
2.增强目标对象
在这里插入图片描述
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

三,优点:

1.代理模式能将代理对象与真实被调用的目标对象分离
2.一定程度上降低了系统的耦合度,扩展性好
3.保护目标对象
4.增强目标对象

四,缺点:

1.代理模式会造成系统设计中类的数目增加
2.在客户端和目标对象增加了一个代理对象,造成请求处理速度变慢
3.增加系统的复杂度

五,扩展:

静态代理: 由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了
动态代理: 在程序运行时通过反射机制动态创建的。在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。真正的代理对象由JDK再运行时为我们动态的来创建。
CGlib代理: JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过 字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
Spring代理选择:当有Bean时,Spring用JDK动态代理,没有时,用CGlib

六,代码演练:

1.Order类

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;
    }
}

2.IOrderService

public interface IOrderService {
    int saveOrder(Order order);

}

3.OrderServiceImpl

public class OrderServiceImpl implements IOrderService {
    private IOrderDao iOrderDao;
    @Override
    public int saveOrder(Order order) {
        //spring会自己注入,现在直接new
        iOrderDao=new IOrderDaoImpl();
        System.out.println("service层调用Dao层添加Order");
        return iOrderDao.insert(order);
    }
}
  1. IOrderDao
public interface IOrderDao {
    int insert(Order order);
}

5.IOrderDaoImpl

public class IOrderDaoImpl implements IOrderDao {
    @Override
    public int insert(Order order) {
        System.out.println("Dao层添加Order成功");
        return 1;
    }
}

6.DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource {
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDBType();
    }
}

7.DataSourceContextHolder

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();
    }
}

8.OrderServiceStaticProxy

public class OrderServiceStaticProxy {
    private IOrderService iOrderService;
    public  int saveOrder(Order order){
        beforeMethod();
        iOrderService =new OrderServiceImpl();
        int userId=order.getUserId();
        int dbBouter=userId%2;
        System.out.println("静态代理分配的db:"+dbBouter+" 处理数据");

        DataSourceContextHolder.setDBType(String.valueOf(dbBouter));

        afterMethod();
        return iOrderService.saveOrder(order);
    }
    private void beforeMethod(){
        System.out.println("静态代理 before code");
    }
    private void afterMethod(){
        System.out.println("静态代理 after code");
    }
}

9.Test 类

public class Test {
    public static void main(String[] args) {
        Order order=new Order();
        order.setUserId(1);
        OrderServiceStaticProxy orderServiceStaticProxy=new OrderServiceStaticProxy();
        orderServiceStaticProxy.saveOrder(order);
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值