第 2 章 基础支持层(上)

news2024/10/10 16:02:45

在这里插入图片描述

2.1 解析器模块

常见的 XML 处理方式

  1. DOM,基于树形结构的 XML 解析方式,它会将整个 XML 文档读入内存并构建一个 DOM 树,基于这棵树形结构对各个节点(Node)进行操作。

  2. SAX,基于事件模型的 XML 解析方式,它不需要将整个 XML 文档加载到内存中,而只需将 XML 文档的一部分加载到内存中。

  3. StAX,JAXP 的后来版本,解析方式与 SAX 类似,也是把 XML 文档作为一个事件流进行处理。不同之处在于 StAX 采用的是“拉模式”。

    在这里插入图片描述

2.1.1 XPath简介

MyBatis 在初始化过程中处理 mybatis-config.xml 配置文件以及映射文件时,使用的是 DOM 解析方式,并结合使用 XPath 解析 XML 配置文件。

2.1.2 XPathParse

MyBatis 提供的 XPathParser 类封装了 XPath、Document 和 EntityResolver。

2.2 反射工具箱

2.2.1 Reflector&ReflectorFactory
  • Reflector 是 MyBatis 中反射模块的基础,每个 Reflector 对象都对应一个类,在 Reflector 中缓存了反射操作需要使用的类的元信息。
  • ReflectorFactory 接口主要实现了对 Reflector 对象的创建和缓存。

TIPS:关于 JavaBean 规范

类中定义的成员变量也称为“字段”,属性则是通过 getter/setter 方法得到的,属性只与类中的方法有关,与是否存在对应成员变量没有关系。例如,存在 getA() 方法和 setA(String) 方法,无论类中是否定义了字段 String a,我们都认为该类中存在属性 a。

2.2.2 TypeParameterResolver

TypeParameterResolver 是一个工具类,它提供了一系列静态方法来解析指定类的字段、方法返回值或方法参数的类型。

2.2.3 ObjectFactory

ObjectFactory 接口提供了多个 create() 方法的重载,通过这些方法可以创建指定类型的对象。

2.2.4 Property 工具集
  1. PropertyTokenizer

    <resultMap id="rm4testProTool" type="User">
        <id column="id" property="id"/>
        <result property="orders[0].items[0].name" column="item1"/>
        <result property="orders[0].items[1].name" column="item2"/>
    </resultMap>
    

    orders[0].items[0].name 这种由 “.” 和 “[]” 组成的表达式是由 PropertyTokenizer 进行解析的。

  2. PropertyNamer,完成方法名到属性名的转换

  3. PropertyCopier,实现相同类型的两个对象之间的属性值的拷贝

2.2.5 MetaClass

MetaClass 通过 Reflector 和 PropertyTokenizer 的组合使用,实现了对复杂的属性表达式的解析,并实现了获取指定属性描述信息的功能。

2.2.6 ObjectWrapper

ObjectWrapper 接口是对对象的包装,抽象了对象的属性信息,它定义了一系列查询对象属性信息的方法。

2.2.7 MetaObject

MetaObject 负责解析属性表达式。

2.3 类型转换

JDBC 数据类型与 Java 语言中的数据类型并不是完全对应的,所以在使用时需要对二者进行转换。

在这里插入图片描述

MyBatis 中使用 JdbcType 枚举代表 JDBC 中的数据类型,该枚举类型中定义了 TYPE_CODE 字段,记录了 JDBC 类型在 java.sql.Types 中相应的常量编码,并通过一个静态集合 codeLookup(HashMap<Integer, JdbcType>) 维护了常量编码与 JdbcType 之间的对应关系。

2.3.1 TypeHandler

MyBatis 中所有的类型转换器都继承了 TypeHandler 接口,在TypeHandler 接口中定义了两类四个方法,其中 setParameter() 方法将数据由 Java 类型转换成 JdbcType 类型;getResult() 方法及其重载负责将数据由 JdbcType 类型转换成 Java 类型。

2.3.2 TypeHandlerRegistry

在 MyBatis 初始化过程中,会为所有已知的 TypeHandler 创建对象,并实现注册到 TypeHandlerRegistry 中,由 TypeHandlerRegistry 负责管理这些对象。

2.3.3 TypeAliasRegistry

MyBatis 将 SQL 语句中别名的概念进行了延伸和扩展,可以为一个类添加一个别名,之后就可以通过别名引用该类。并通过 TypeAliasRegistry 完成对别名的注册和管理。

2.4 日志模块

2.4.1 适配器模式

适配器模式的主要目的是解决由于接口不能兼容而导致类无法使用的问题,适配器模式会将需要甜酸的类转换成调用者能够使用的目标接口。涉及以下角色:

  1. 目标接口(Target):调用者能够直接使用的接口
  2. 需要适配的类(Adaptee):一般情况下,Adaptee 类中有真正的业务逻辑,但是其接口不能被调用者直接使用。
  3. 适配器(Adapter):Adapter 实现了 Target 接口,并包装了一个 Adaptee 对象。Adapter 在实现 Target 接口中的方法时,会将调用委托给 Adaptee 对象,由后者完成具体的业务。

使用适配器模式的好处就是复用现有组件。这符合开闭原则,当有新的 Adaptee 需要被复用时,只要添加新的 Adapter 即可。

在 MyBatis 的日志模块中,就使用了适配器模式。MyBatis 使用内部接口(logging.Log)完成日志模块。并提供多种 Adapter 来集成和复用 Log4j,Log4j2 等三方日志组件。

2.4.2 日志适配器

MyBatis 统一提供了 trace、debug、warn、error 四个日志级别,可以满足绝大多数场景的日志需求。

2.4.3 代理模式与 JDK 动态代理

在这里插入图片描述

如图,Subject 是程序中的业务逻辑接口,RealSubject 是实现了 Subject 接口的真正业务类,Proxy 是实现了 Subject 接口的代理类,其中封装了 RealSubject 对象。程序中不会直接调用 RealSubject 对象的方法,而是使用 Proxy 对象实现相关的功能。这就是所谓的“代理模式”。

除了上述的“静态代理模式”(在编译阶段就为每个被代理类创建一个 Proxy 类),还可以使用动态代理。JDK 通过 InvocationHandler 接口,提供了动态代理的解决方案。

package com.example.chapter2.section4;

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

public class TestInvokerHandler implements InvocationHandler {

    private Object target; // 真正的业务对象,也就是 RealSubject 对象

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // ……在执行真正的业务方法之前的预处理操作……
        Object result = method.invoke(target, args);// 调用真正的业务方法
        // ……在执行真正的业务方法之后的后续处理操作……
        return result;
    }

    public Object getProxy() {
        // 创建代理对象
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
    }

    public static void main(String[] args) {
        // 创建真正的业务对象
        Subject realSubject = new RealSubject();
        // 创建 InvocationHandler 对象
        TestInvokerHandler handler = new TestInvokerHandler(realSubject);
        // 创建代理对象
        Subject proxySubject = (Subject) handler.getProxy();
        // 调用代理对象的方法
        proxySubject.operation();
    }
}
2.4.4 JDBC调试

MyBatis 日志模块中有一个 Jdbc 包,通过 JDK 动态代理的方式,将 JDBC 操作通过指定的日志框架打印出来。这个功能通常在开发阶段使用,它可以输出 SQL 语句、用户传入的绑定参数、SQL 语句影响行数等信息。

2.5 资源加载

2.5.1 类加载器简介
  1. JVM 中的类加载器(ClassLoader)负责加载来自文件系统、网络或其他来源的类文件

  2. 有三种默认使用的类加载器

    Bootstrap ClassLoader负责加载 JDK 自带的 rt.jar 包中的类文件所有类加载器的父加载器,没有任何父加载器
    Extension ClassLoader负责加载 Java 的扩展类库,即 jre/lib/ext 或 java.ext.dirs 指定的目录下的类文件System ClassLoader 的子加载器
    System(Application) ClassLoader负责从 classpath 环境变量中加载类文件,classpath 通常由 “-classpath” 或 “-cp” 命令行选项定义,或是由 JAR 中 Manifest 文件的 classpath 属性指定。Extension ClassLoader 的子加载器
  3. JVM 类加载器默认使用双亲委派模式——在加载类文件时,子加载器首先会将加载请求委托给它的父加载器。父加载器会检测自己是否已经加载过该类,如果已经加载过则加载过程结束;如果没有加载过,则请求继续向上传递直到 Bootstrap ClassLoader,最终由 Bootstrap ClassLoader 加载该类文件,如果加载失败则由子加载器尝试加载,直接发起加载请求的子加载器为止。双亲委派模式可以保证:1)子加载器可以使用父加载器已加载的类;2)父加载器已加载过的类无法被子加载器再次加载。保证了 JVM 的安全性和稳定性。

    在这里插入图片描述

  4. 可以通过继承 java.lang.ClassLoader 类的方式实现自定义类加载器,以满足特殊需要。

2.5.2 ClassLoaderWrapper

MyBatis 的 IO 包中封装了 ClassLoader 以及读取资源文件的相关 API。ClassLoaderWrapper 是一个 ClassLoader 的包装器,其中包含了多个 ClassLoader 对象。通过调整多个类加载器的使用顺序,ClassLoaderWrapper 可以确保返回 给系统使用的是正确的类加载器。

2.5.3 ResolverUtil

ResolverUtil 可以根据指定的条件查找指定包下的类,其中使用的条件由 Test 接口表示。

2.5.4 单例模式

所谓单例模式,是指在整个系统中,单例类只能有一个实例对象,且需要自行完成示例,并始终对外提供同一实例对象。

写法一:双端检锁

package com.example.chapter2.section5;

public class Singleton {
    
    // 使用 volatile 修饰 instance 变量
    private static volatile Singleton instance = null;
    
    // 私有构造方法
    private Singleton() {
    }
    
    // 静态方法
    public static Singleton getInstance() {
        // 第一次检查 instance 是否为 null
        if (instance == null) {
            // 加锁
            synchronized (Singleton.class) {
                // 第二次检查 instance 是否为 null
                if (instance == null) {
                    // 创建实例
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

写法二:静态内部类

package com.example.chapter2.section5;

public class Singleton6 {

    // 私有的静态内部类,该静态内部类只会在newInstance()方法中被加载
    private static class SingletonHolder {
        // 静态初始化器,由JVM来保证线程安全
        private static final Singleton6 instance = new Singleton6();
    }

    // 私有构造方法
    private Singleton6() {
    }

    // 静态方法
    public static Singleton6 newInstance() {
        return SingletonHolder.instance;
    }
}
2.5.5 VFS

虚拟文件系统(Virtual File System),它用来查找指定路径下的资源。MyBatis 提供了 JBoss6VFS 和 DefaultVFS 两个 VFS 的实现。

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

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

相关文章

如何制作低代码开发的视频教程?

如何制作低代码开发的视频教程&#xff1f; 随着数字化转型的加速&#xff0c;越来越多的企业和组织开始采用低代码开发平台来加速应用程序的构建。对于许多开发者和业务人员来说&#xff0c;学习如何使用这些平台可以显著提高工作效率。因此&#xff0c;创建一份清晰、实用且…

数字化AI新赋能,智享AI直播:开启一个全新的直播时代!

数字化AI新赋能&#xff0c;智享AI直播&#xff1a;开启一个全新的直播时代! 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;AI直播技术的崛起&#xff0c;无疑是数字化时代的一大亮…

springMVC添加webapp

项目结构-->模块-->找到想添加的模块下的web 点击号 添加路径 会在.../src/main/目录下自动生成目录

Javaava版本ERP管理系统源码-打造企业核心竞争力:ERP管理系统创新实践

在数字化转型的浪潮中&#xff0c;企业对于高效、稳定且易于扩展的管理系统的需求日益增长。为了满足这一需求&#xff0c;我们开发了一款基于Java技术的ERP&#xff08;Enterprise Resource Planning&#xff09;管理系统&#xff0c;该系统通过Spring Cloud Alibaba、Spring …

Axios 网络请求

文章目录 Axios 网络请求1.Axios 使用1.Axios 简介2.Axios 安装安装命令 3.Axios 引入方式全局引入局部引入 2.整合 vue1.在组件中使用 axios 发送请求发送结果这里就出现了跨域问题 3.跨域后端解决办法全局配置类 加入注解 CrossOrigin请求结果 全局配置 baseUrl Axios 网络请…

dressler电源维修LFGS-1250C射频电源维修

LFGS射频发生器是用于半导体生产和一般等离子处理的多功能射频发生器。此类可变频率发生器采用了一种半桥、D类型放大器理念&#xff0c;是一种空冷式紧凑型的设计&#xff0c;可安装在19英寸机架上面。应用包括溅射、等离子蚀刻、化学气象沉积、聚合以及表面处理设备上。 维修…

电抗器运行噪声振动规范

电抗器在运行过程中会产生一定的噪声和振动&#xff0c;特别是在大功率、高电流条件下。因此&#xff0c;为了保证电抗器的安全运行和降低噪声对环境的影响&#xff0c;需遵循相关规范和标准。以下是电抗器运行噪声和振动的常见规范和要求&#xff1a; 一、噪声规范 电抗器的…

基于ADS的混频器设计

混频器是射频微波电路系统中不可或缺的部件。 无论是微波通信、 雷达、 遥控、 遥感&#xff0c;还是侦察与电子对抗&#xff0c;以及许多微波测量系统&#xff0c;都必须把微波信号用混频器降到中低频来进行处理。 因为集成式混频器体积小&#xff0c;设计技术成熟&#xff0c…

动态感知,趋势预警,非可视化大屏莫属

动态感知与趋势预警至关重要。而此时&#xff0c;非可视化大屏莫属。它如同一个智慧的窗口&#xff0c;将复杂的数据转化为直观的图像与动态图表。实时更新的数据在大屏上跳动&#xff0c;让你清晰把握每一个变化瞬间。无论是市场趋势的微妙波动&#xff0c;还是业务进展的动态…

Vue2 ant-design 设置mode=“[‘month‘, ‘month‘]“时,选择时间后弹框不关闭

废话不多说&#xff0c;直接上代码&#xff1a; <template><div class"page-main"><a-range-pickervalue-format"YYYY-MM"format"YYYY-MM"v-model"billMonth":open"monthPickShow"panelChange"handleP…

点云深度学习方法

深度学习点云数据处理主要涉及&#xff1a; 分类(Classification)、分割(Segmentation)、目标检测&#xff08;Object Detection&#xff09;、实例分割(Panoptic Segmentation)、配准(Registration)、点云重构(Reconstruction)。 论文&#xff1a;Deep Learning for 3D Poin…

深入解析 DolphinScheduler 任务调度、拆分与执行全流程

Apache DolphinScheduler介绍 Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景&#xff0c;提供了一个可视化操作任务、工作流和全生命周期数据处理过程的解决方案。 Dag背景知识 摘录了一下Dag的offical定义 A graph is f…

宠物空气净化器该怎么选?希喂,小米、安德迈这三款好用吗?

不得不说&#xff0c;虽然现在购物网站的活动不少&#xff0c;可力度都好弱啊&#xff01;我想买宠物空气净化器很久了&#xff0c;觉得有点贵&#xff0c;一直没舍得入手。价格一直没变化&#xff0c;平台小活动根本没什么优惠&#xff0c;只能寄希望于双十一了&#xff0c;准…

开源项目|“智慧光伏”开源项目技术文档

【基于ELF 1开发板完成的“智慧光伏”项目】 “智慧光伏”项目能够智能追踪阳光的移动轨迹。通过内置的光敏传感器和智能控制系统&#xff0c;实时感知周围光源的变化&#xff0c;并驱动太阳能板精准调整角度&#xff0c;确保每一缕阳光都能被最大化地捕捉和利用。下面就和各位…

爬虫常用正则表达式用法

在网页爬虫中&#xff0c;正则表达式&#xff08;regex&#xff09;是一种非常有用的工具&#xff0c;用于从 HTML、JSON 或其他文本格式中提取特定的数据。下面是一些常见的正则表达式及其在爬虫中的应用场景&#xff1a;

如何利用phpstudy创建mysql数据库

phpStudy诞生于2007年&#xff0c;是一款老牌知名的PHP开发集成环境工具&#xff0c;产品历经多次迭代升级&#xff0c;目前有phpStudy经典版、phpStudy V8&#xff08;2019版&#xff09;等等&#xff0c;利用phpstudy可以快速搭建一个mysql环境&#xff0c;接下来我们就开始吧…

Html 标题加图标

每个网页选项卡都有一个图标&#xff1a; <meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>主页</title><link rel"icon" href"images/记事本.png&…

linux系统不同用户登录vnc

说明&#xff1a;安装oracle时需要用oracle用户登录&#xff0c;配置vnc使用oracle用户登录 1.修改/etc/sysconfig/vncservers&#xff0c;添加oracle用户 VNCSERVERS“1:root 2:oracle” VNCSERVERARGS[1]“-geometry 1024x768” VNCSERVERARGS[2]“-geometry 1024x768” VN…

Scrapy:简单使用、xpath语法

简单使用 简介 Scrapy 是一个为了爬取网站信息&#xff0c;提取结构性数据而编写的应用框架&#xff0c;可以用于数据挖掘、检测和自动化测试。 架构 组件 引擎&#xff0c;指挥其他组件协同工作调度器 &#xff0c;接收引擎发过来的请求&#xff0c;按照先后顺序&#xff0…

APP的命令和monkey压力测试

一、命令的使用&#xff1a; 1.dos下链接&#xff1a;adb connect 127.0.0.1:62001 2.所附设备清单&#xff1a;adb devices device:已识别的设备&#xff0c;表示连接成功 unauthorized:没有授权需要手机授权才能连接 unkown:未识别设备 offline:离线设备 3.版本&#xff1a;…