简单创建代理工厂

news2024/9/23 3:23:31

简单创建代理工厂

一般对于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);

    }
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2041925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2766:最大子矩阵

网址如下&#xff1a; OpenJudge - 2766:最大子矩阵 用dp来做就行了 代码如下&#xff08;MLE&#xff09;&#xff1a; #include<cstdio>const int maxn 101; int dp[maxn][maxn][maxn][maxn]; int martix[maxn][maxn]; int N, ans;int main(void) {scanf("%d&q…

jackson 轻松搞定接口数据脱敏

一、简介 实际的业务开发过程中&#xff0c;我们经常需要对用户的隐私数据进行脱敏处理&#xff0c;所谓脱敏处理其实就是将数据进行混淆隐藏&#xff0c;例如下图&#xff0c;将用户的手机号、地址等数据信息&#xff0c;采用*进行隐藏&#xff0c;以免泄露个人隐私信息。 如…

C++_基本语法笔记_模板

函数模板 基本使用 思想是Java里的泛型&#xff08;不确定用什么类型的数据&#xff09; 这里template这一句&#xff0c;意思是声明T是泛型&#xff0c;后面写用到泛型T的函数。 建议都用template<class T> 应用场景&#xff1a;不同数据类型的交换函数 两种使用方法…

猫咪泪痕消除术!希喂主食罐开启补水大作战!

我家小猫之前的泪痕真的不是一般的严重&#xff0c;每天都能看到它眼角挂着两条明显的褐色痕迹&#xff0c;我每天早晚都得小心翼翼地帮它擦拭&#xff0c;但效果总是微乎其微&#xff0c;眼眶边总是留下那么一圈顽固的黑色痕迹&#xff0c;我真是既忧心又无奈。 后来&#xff…

2024【十大品牌网】发布|车载WiFi十大品牌排行榜

自驾游无法随时随地联网?货车司机流量不够用&#xff1f;网约车线上抢单网速不好&#xff1f;来看看最新发布的车载WiFi十大品牌排行榜&#xff0c;帮你解决网速慢、流量不够用的问题&#xff01; 1.格行 格行作为有15年历史的老牌物联网企业&#xff0c;在产品质量和服务上…

沃可趣助力乐园工会:员工活动的数字化创新与实践

企业组织员工活动难处多多 预算不足都算轻的&#xff0c;时间协调也颇有难度&#xff0c;活动内容设计更是既要激发员工兴趣&#xff0c;又要符合企业文化&#xff0c;这让原本专注于OA服务和福利平台开发的公司纷纷退缩。 因此&#xff0c;当群硕决定在沃可趣上增加活动管理…

渲染优化策略,如何在有限资源下实现最佳视觉效果

在数字内容创作领域&#xff0c;渲染是一个至关重要的环节&#xff0c;它决定了最终图像或动画的视觉质量。然而&#xff0c;高质量的渲染往往伴随着高计算资源需求&#xff0c;如何在有限资源下实现最佳的视觉效果&#xff0c;成为了创作者们不断探索的课题。 一、优化3D模型…

青颖飞帆(青书)大模型算法工程师面试题6道|含解析

问题1、Decoder-Only和Encoder-Decoder模型相比有什么优势&#xff1f;在训练和推理效率上有什么区别&#xff1f;**** Decoder-Only模型&#xff1a;结构较为简洁&#xff0c;通常只由一个解码器组成。模型参数较少&#xff0c;相比于Encoder-Decoder模型在训练和推理上可能更…

UE5学习笔记9-创建一个小窗口提示人物是否和武器重叠

一、目标 创建一个UsrWidget去显示如果人物和武器重叠显示窗口&#xff0c;如果人物和武器不重叠将窗口隐藏 二、创建窗口并显示 1.创建一个窗口蓝图类&#xff0c;命名为PickUpWidget&#xff0c;这个蓝图类不需要C类&#xff0c;在对应文件夹中单机右键选择用户界面的控件蓝…

torch分布式训练DataParallel和DistributedDataParallel

Pytorch 分布式训练主要有两种方式&#xff1a; torch.nn.DataParallel > 简称 DP torch.nn.parallel.DistributedDataParallel > 简称DDP 其中 DP 只用于单机多卡&#xff0c;DDP 可以用于单机多卡也可用于多机多卡&#xff0c;后者现在也是Pytorch训练的主流用法&…

维基知识库系统Wiki.js本地Linux环境部署并配置公网地址远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

所生成项目的处理器架构“MSIL”与引用“***”的处理器架构“x86”不匹配。

在c#工程里新建了一个类库&#xff0c;编译的场合出现以下警告&#xff1a;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2401,5): warning MSB3270: 所生成项目的处理器架构“MSIL”与引用“…

单链表leetcode刷题/下(C语言版)

目录 题目1&#xff1a;返回倒数第k个结点 题目2&#xff1a;回文链表 题目3&#xff1a;相交链表 题目1&#xff1a;返回倒数第k个结点 如图&#xff0c;该题使用到了快慢指针的思想。先定义两个指针&#xff0c;同时指向链表的首元结点&#xff0c;然后让fast指针向前先走…

秋招突击——8/15——知识补充——Socket通信

文章目录 引言正文基于TCP协议的Socket通信基于UDP协议的Socket通信服务端如何接收更多项目多进程多线程IO多路复用select轮询IO多路复用epoll事件通知 使用Socket实现同一个机器上的多线程通信服务端创建对应socket监听端口客户端发起对应的连接请求 总结 引言 上次面试腾讯的…

Qt篇——:-1: error: collect2.exe: error: ld returned 1 exit status错误

错误如图所示&#xff1a; 出现这个错误的时候我们点击下面的 [4 编译输出]&#xff0c;可以看到具体的编译报错信息&#xff0c;找到对应的错误进行解决即可。 这里举个例子&#xff0c;比如最常见的一种错误原因是&#xff1a;multiple definition of ......。这代表着你重复…

视频号小店升级微信小店,视频号直播电商将迎来新变化!

8月12日&#xff0c;腾讯发布《视频号小店升级为微信小店的公告》-意见征集通知&#xff0c;及其相关规则通知。 ▲ 图片来源&#xff1a;腾讯公告 公告称&#xff1a;腾讯计划自08月25日起&#xff0c;正式支持商家将视频号小店升级成微信小店。 微信小店将进一步简化商家入驻…

C++语言基础|循环结构

C语言基础|循环结构 循环1. for语句2. while循环3. do…while语句 循环 在程序中&#xff0c;常常需要重复地执行某些操作。C提供了3种循环语句&#xff1a;for语句、while语句和do-while语句。在循环语句中&#xff0c;重复执行的操作叫做循环体。循环体可以是单条语句、块语…

一把手在精益生产的实施中扮演着怎样的角色?

在探讨一把手在精益生产实施中的角色时&#xff0c;我们不得不深入剖析精益生产的核心要义及其在现代企业管理中的重要性。精益生产作为一种以提高效率、降低成本、增加价值为目标的生产管理方式&#xff0c;其核心理念包括价值导向、流动制造、消除浪费、持续改进等。在这个过…

ubuntu服务器部署的mysql本地连不上的问题

试过了网上的所有方法,都连不上,可以执行: SELECT user, host, plugin FROM mysql.user WHERE user root; 查一下:plungin这个连接插件是不是auth_socket, auth_socket是只能本地连接的插件,需要修改: ALTER USER root% IDENTIFIED WITH mysql_native_password BY your_pass…

攀登SEO巅峰:代理技术如何成为网站排名提升的秘密武器

在当今这个数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为企业和电商从业者在网站获取自然流量、提升品牌知名度和促进业务增长的关键策略之一。然而&#xff0c;随着搜索引擎算法的不断升级和市场竞争的日益激烈&#xff0c;传统的SEO手段已难以满足现…