简单创建代理工厂

简单创建代理工厂

一般对于JDBC来说,无非就是连接数据库、查询数据库、封装实体、返回实体,如果要设计一个ORM框架的话也就是要考虑怎么把用户自定义的数据库操作接口、XML中的SQL语句、数据库三者给联系起来,其实最适合的操作就是代理,使用代理的方式来进行处理,因为代理可以封装一个复杂的流程为借口对象的实现类。

这张图描述了一个使用代理模式的流程,主要涉及IUserDao接口及其代理对象的创建和调用。以下是详细解释:

  1. IUserDao 接口

    • 该接口定义了一个方法 queryUserName(),用于查询用户名。
  2. MapperProxyFactory

    • 这是一个代理工厂类,用于创建代理对象。它根据 IUserDao 接口生成相应的代理。
  3. MapperProxy

    • 这是实际的代理类。MapperProxyFactory 会创建一个 MapperProxy 实例,该实例包装了 IUserDao 的具体操作。
    • MapperProxy 接收到方法调用后,会拦截并处理这些调用。
  4. 代理对象

    • MapperProxyFactory 创建的代理对象,实现了 IUserDao 接口,并会将 queryUserName() 的调用代理给 MapperProxy 处理。
  5. 实际调用

    • 当你调用代理对象的 queryUserName() 方法时,实际上是由 MapperProxy 进行处理的,它包装了具体的 Mapper 操作。
  6. 包装 Mapper 操作

    • MapperProxy 内部会包装具体的 Mapper 操作,比如执行 SQL 查询等,从而实现 queryUserName() 的功能。

这个流程图展示了如何通过代理工厂和代理模式,动态创建 IUserDao 接口的代理对象,并通过代理对象来处理接口方法的调用,从而实现接口的具体操作。

首先是IUserDao

package com.hayaizo.test.dao;

public interface IUserDao {

    String queryUserName(String uid);

    String queryUserAge(String uid);
}

映射器代理类

package com.hayaizo.binding;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 映射器代理类
 * 实现了 InvocationHandler 接口和 Serializable 接口
 */
public class MapperProxy<T> implements InvocationHandler, Serializable {

    // 序列化版本号,用于反序列化时的一致性校验
    private static final long serialVersionUID = -238941387264L;

    // SQL 会话,用于存储 SQL 映射,现在用Map模拟
    private Map<String, String> sqlSession;

    // 被代理的接口类
    private final Class<T> mapperInterface;

    /**
     * 构造方法
     *
     * @param sqlSession      SQL 会话
     * @param mapperInterface 被代理的接口类
     */
    public MapperProxy(Map<String, String> sqlSession, Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
        this.sqlSession = sqlSession;
    }

    /**
     * 代理方法的实际调用处理逻辑
     *
     * @param proxy  代理对象
     * @param method 被调用的方法
     * @param args   方法参数
     * @return 方法调用的结果
     * @throws Throwable 可能抛出的异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 如果方法是 Object 类的方法,直接调用
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else {
            // 否则,通过 sqlSession 获取对应的 SQL 语句,并返回
            // 这里返回一个字符串,表示被代理的方法被调用
            return "你被代理了!" + sqlSession.get(mapperInterface.getName() + "." + method.getName());
        }
    }
}

映射器工厂

package com.hayaizo.binding;

import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * 映射器的代理工厂
 */
public class MapperProxyFactory<T> {

     private final Class<T> mapperInterface;

    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    public T newInstance(Map<String,String> sqlSession) {
        //提供一个代理类
        MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession,mapperInterface);
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
    }
}

测试方法

package com.hayaizo.test.dao;

import com.hayaizo.binding.MapperProxyFactory;
import org.junit.Test;

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class ApiTest {

    @Test
    public void test_proxy_class(){
        IUserDao userDao = (IUserDao) Proxy.newProxyInstance(
                Thread.currentThread().getContextClassLoader(),
                new Class[]{IUserDao.class},
                (proxy, method, args) -> {
                    if ("queryUserName".equals(method.getName())) {
                        return "你被代理了"+" args= "+args[0];
                    } else if ("queryUserAge".equals(method.getName())) {
                        return "18";
                    }
                    return method.invoke(this,args);
                }
        );
        String res = userDao.queryUserName("1");
        String res1 = userDao.queryUserAge("1");
        System.out.println(res);
        System.out.println(res1);
    }

    @Test
    public void test_MapperProxyFactory(){
        MapperProxyFactory<IUserDao> mapperProxyFactory = new MapperProxyFactory<>(IUserDao.class);
        Map<String,String> sqlSession = new HashMap<>();
        //com.hayaizo.test.dao.IUserDao
        sqlSession.put("com.hayaizo.test.dao.IUserDao.queryUserName","模拟执行Mapper.xml中的SQL语句,操作:查询用户名称");
        IUserDao userDao = mapperProxyFactory.newInstance(sqlSession);
        String string = userDao.queryUserName("1");
        System.out.println(string);

    }
}

运行结果:

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值