您当前的位置: 首页 >  Java

小志的博客

暂无认证

  • 0浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

java设计模式——动态代理示例

小志的博客 发布时间:2021-01-06 22:34:04 ,浏览量:0

动态代理示例实现动态分库功能示例

1、代码结构如下图: 在这里插入图片描述

2、创建订单和用户类

package com.rf.designPatterns.structural.proxy;

/**
 * @description: 订单和用户类
 * @author: xz
 */
public class Order {
    private Object orderId;//订单id
    private Integer userId;//用户id

    public Object getOrderId() {
        return orderId;
    }

    public void setOrderId(Object orderId) {
        this.orderId = orderId;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}

3、创建Service层

package com.rf.designPatterns.structural.proxy;

/**
 * @description: Service层
 * @author: xz
 */
public interface OrderService {
    int saveOrder(Order order);
}

4、创建Dao层

package com.rf.designPatterns.structural.proxy;

/**
 * @description: Dao层
 * @author: xz
 */
public interface OrderDao {
    int insert(Order order);
}

5、创建Dao实现层

package com.rf.designPatterns.structural.proxy;

/**
 * @description: Dao实现层
 * @author: xz
 */
public class OrderDaoImpl implements OrderDao{
    @Override
    public int insert(Order order) {
        System.out.println("Dao层添加订单成功");
        return 1;
    }
}

6、创建Service实现层

package com.rf.designPatterns.structural.proxy;

/**
 * @description: Service实现层
 * @author: xz
 */
public class OrderServiceImpl implements OrderService{
    private OrderDao orderDao;
    @Override
    public int saveOrder(Order order) {
        //spring会自动注入,这里我们自己直接new
        orderDao=new OrderDaoImpl();
        System.out.println("Service调用Dao层的inser方法添加订单");
        orderDao.insert(order);
        return 1;
    }
}

7、创建数据源上下文类

package com.rf.designPatterns.structural.proxy.db;

/**
 * @description: 数据源上下文类
 * @author: xz
 */
public class DataSourceContextHolder {

    private static final ThreadLocal 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();
    }

}

8、创建动态的数据源类

package com.rf.designPatterns.structural.proxy.db;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * @description: 动态的数据源类
 * @author: xz
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDBType();
    }
}

9、创建Service层的动态代理

package com.rf.designPatterns.structural.proxy.dynamicProxy;

import com.rf.designPatterns.structural.proxy.Order;
import com.rf.designPatterns.structural.proxy.db.DataSourceContextHolder;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @description: Service层的动态代理
 * @author: xz
 */
public class OrderServiceDynamicProxy implements InvocationHandler {
    //声明一个目标对象
    private Object target;

    //通过构造器添加目标对象
    public OrderServiceDynamicProxy(Object target) {
        this.target = target;
    }

    //绑定目标对象
    public Object bind(){
        Class cls=target.getClass();//获取目标类的class对象
        return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this);
    }


    /**
     * @param proxy 动态生成的代理类
     * @param method 要被增强的方法对象
     * @param args method方法的参数
     * @return
     * @throws Throwable
     */
    @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){
        System.out.println("动态代理before代码, 在invoke方法之前执行");
        int userId=0;
        if(obj instanceof Order){
            Order order=(Order)obj;
            userId= order.getUserId();
        }
        int dbRouter=userId % 2;
        System.out.println("动态代理分配到 db【" +dbRouter+ "】 数据库处理数据");
        DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter));
    }

    private void afterMethod(){
        System.out.println("动态代理after代码, 在invoke方法之后执行");
    }

}

10、创建测试类

package com.rf.designPatterns.structural.proxy.dynamicProxy;

import com.rf.designPatterns.structural.proxy.Order;
import com.rf.designPatterns.structural.proxy.OrderService;
import com.rf.designPatterns.structural.proxy.OrderServiceImpl;

public class Test {

    public static void main(String[] args) {

        Order order=new Order();
        //order.setUserId(1);
        order.setUserId(2);
        OrderService  orderServiceDynamicProxy = (OrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind();
        orderServiceDynamicProxy.saveOrder(order);

    }
}

11、测试结果如下图:

在这里插入图片描述

关注
打赏
1661269038
查看更多评论
立即登录/注册

微信扫码登录

0.0463s