代理模式

一.定义

  • 为其他对象提供一种代理,以控制对这个对象的访问。
  • 代理对象在客户端和目标对象之间起到中介的作用
  • 代理对象可以对被代理对象进行方法增强
  • 代理模式属于结构型模式。

二.静态代理

  • 静态代理的实现比较简单,代理类中声明被代理的对象,并对被代理对象中的方法进行声明,并定义用于增强目标方法的函数。直接进行显式的配置即可
    静态代理
  • 静态代理类OrderServiceStaticProxy想要代理OrderServiceImpl中的saveOrder方法。通常就是在OrderServiceStaticProxy中定义同名方法与具体增强代码,安插在目标方法的前后。
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;
    }
}
public interface IOrderService {
    int saveOrder(Order order);
}
public class OrderServiceImpl implements IOrderService {
    private IOrderDao orderDao;
    @Override
    public int saveOrder(Order order) {
        orderDao = new OrderDaoImpl();
       // System.out.println("Service层调用Dao层添加Order");
        return orderDao.insert(order);
    }
}
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;
    }
}
public class DataSourceContextHolder {
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    public static void setDBType(String dbType){
        CONTEXT_HOLDER.set(dbType);
    }
    public static String getDBType(){
        return CONTEXT_HOLDER.get();
    }
    public static void clearDBType(){
        CONTEXT_HOLDER.remove();
    }
}
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDBType();
    }
}
public class OrderServiceStaticProxy {

    private IOrderService orderService;

    public int saveOrder(Order order){
        beforeMethod(order);
        orderService = new OrderServiceImpl();
        int result = orderService.saveOrder(order);
        afterMethod();
        return result;

    }
    //执行方法前
    private void beforeMethod(Order order){
        Integer userId = order.getUserId();
        int dbRouter = userId % 2;
        System.out.println("静态代理分配到["+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);
    }
}

三.动态代理

  • 通过实现java.lang.reflect.InvocationHandler接口,完成动态代理。
//  每个代理实例都有一个关联的调用处理程序。
//  在代理实例上调用方法时,该方法调用被编码并分派到{@code invoke}其调用处理程序的方法。
public class OrderServiceDynamicProxy implements InvocationHandler {

    private Object target;

    public OrderServiceDynamicProxy(Object target) {
        this.target = target;
    }


    public Object bind(){
        Class targetClass = target.getClass();
        return Proxy.newProxyInstance(targetClass.getClassLoader(),targetClass.getInterfaces(),this);
    }
    /*
     * @Description //TODO 处理代理实例上的方法调用并返回
     * @Date 2019/4/4
     * @Param [proxy 调用该方法的代理实例
     *         method 在代理实例上调用的接口方法
     *         args 包含值的对象数组
     *         ]
     * @return java.lang.Object 从方法调用返回的值
     **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object argObject = args[0];
        beforeMethod(argObject);
        // 原始对象原始方法原始参数原始返回值
        // target 从中调用基础方法的对象 是OrderServiceImpl对象
        // args 用于方法调用的参数  是Order对象
        // return 调度表示的方法的结果
        Object object = method.invoke(target, args);
        afterMethod();
        return object;
    }

    private void beforeMethod(Object object){
        int userId = 0;
        System.out.println("动态代理 before code ");
        if(object instanceof Order){
            Order order = (Order) object;
            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 static void main(String[] args) {
        Order order = new Order();
        order.setUserId(1);
        //创建代理类,并注入目标类
        IOrderService orderServiceDynamicProxy =
                (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind();
        orderServiceDynamicProxy.saveOrder(order);
    }
  • 与之前的静态代理实现相同的功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值