Spring之xml方式整合第三方框架

news2024/12/29 0:14:19

目录

一:概述

二:代码演示 

二:Spring整合MyBatis的原理剖析

三:案例演示


一:概述

 xml整合第三方框架有两种整合方案:

  • 不需要自定义名空间,不需要使用Spring的配置文件配置第三方框架本身内容,例如:MyBatis;

  • 需要引入第三方框架命名空间,需要使用Spring的配置文件配置第三方框架本身内容,例如:Dubbo。

            Spring整合MyBatis,之前已经在Spring中简单的配置了SqlSessionFactory, 但是这不是正规的整合方式,MyBatis提供了mybatis-spring.jar专门用于两大框架的整合。 Spring整合MyBatis的步骤如下:

  • 导入MyBatis整合Spring的相关坐标;(请见资料中的pom.xml)

  • 编写Mapper和Mapperxml;

  • 配置SqlSessionFactoryBean和MapperScannerConfigurer;

  • 编写测试代码

二:代码演示 

①:原始方式使用Mybatis

1.创建BookMapper类和BookMapper.xml文件

package com.tangyuan.mapper;

import com.tangyuan.pojo.Book;

import java.util.List;

/**
 * @author 唐渊
 * @create  2022-11-30 14:27
 */
public interface BookMapper {
      List<Book> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tangyuan.mapper.BookMapper" >
    <select id="findAll" resultType="com.tangyuan.pojo.Book">
        select
         *
        from t_book
    </select>

</mapper>

2.在mybatis-config.xml中引用文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/bookshop?useSSL=false"></property>
                <property name="username" value="root"></property>
                <property name="password" value="1234"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.tangyuan.mapper"/>
    </mappers>
</configuration>

3.编写原始测试代码

package com.tangyuan.test;

import com.tangyuan.mapper.BookMapper;
import com.tangyuan.pojo.Book;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author 唐渊
 * @create  2022-11-30 14:35
 */
public class MyBatisTest {

    public static void main(String[] args) throws Exception {
        //读取配置文件
        //静态工厂方法方式
        InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
        //设置构造器
        //无参构造实例化
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        //构建工厂
        //实例工厂方法
        SqlSessionFactory build = builder.build(resource);
        SqlSession sqlSession = build.openSession();
        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
        List<Book> all = mapper.findAll();
          for (Book a:all){
              System.out.println(a);
          }
    }

}

----------------------------------------------------整合代码操作-----------------------------------------------------------

1.在pom文件引入依赖

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>2.0.7</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.3.20</version>
</dependency>

 2.在主xml文件中进行文件的配置

 <!--1.配置SqlSessionFactoryBean,作用将SqlSessionFactory存储到Spring容器-->
     <bean class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"></property>
     </bean>



<!--配置数据源信息-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/bookshop"></property>
    <property name="username" value="root"></property>
    <property name="password" value="1234"></property>
</bean>

   <!--2.扫描指定的包,产生Mapper对象存储到Spring容器-->
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage"  value="com.tangyuan.mapper"></property>
 </bean>

3.在需要方法的类上调用方法

//需要Mapper,直接注入Mapper和提供set方法
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
    this.bookMapper = bookMapper;
}




//输出集合
@Override
public  void  show(){
    List<Book> all = bookMapper.findAll();
        all.forEach(System.out::println);
  }

4.在xml文件上进行bean的配置

<bean id="userService" class="com.tangyuan.service.impl.UserServiceImpl">
    <property name="bookMapper" ref="bookMapper"></property>
</bean>

5.测试

//创建ApplicationContext,加载配置文件,实例化容器
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = (IUserService) applicationContext.getBean("userService");
userService.show();

二:Spring整合MyBatis的原理剖析

        整合包里提供了一个SqlSessionFactoryBean和一个扫描Mapper的配置对象,SqlSessionFactoryBean一旦被实例化, 就开始扫描Mapper并通过动态代理产生Mapper的实现类存储到Spring容器中。相关的有如下四个类:

  • SqlSessionFactoryBean:需要进行配置, 用于提供SqlSessionFactory;

  • MapperScannerConfigurer:需要进行配置,用于扫描指定mapper注册BeanDefinition;

  • MapperFactoryBean:Mapper的FactoryBean, 获得指定Mapper时调用getObject方法;

  • ClassPathMapperScanner:definition.setAutowireMode(2) 修改了自动注入状态,所以 MapperFactoryBean中的setSqlSessionFactory会自动注入进去。

            Spring整合其他组件时就不像MyBatis这么简单了, 例如Dubbo框架在于Spring进行整合时, 要使用Dubbo提供的命名空间的扩展方式, 自定义了一些Dubbo的标签

<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--配置应用名称-->
<dubbo:applicationname="dubbo1-consumer"/>
<!--配置注册中心地址-->
<dubbo:registryaddress="zookeeper://localhost:2181"/>
<!--扫描dubbo的注解-->
<dubbo:annotationpackage="com.itheima.controller"/>
<!--消费者配置>
<dubbo:consumercheck="false"timeout="1000"retries="o"/>
</beans>

       为了降低我们此处的学习成本, 不在引入Dubbo第三方框架了, 以Spring的context命名空间去进行讲解, 该方式也是命名空间扩展方式。 需求:加载外部properties文件, 将键值对存储在Spring容器中

jdbc.url=jdbc:mysql://localhost:3306/db_shopping
jdbc.username=root
jdbc.password=1234

1.创建外部properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bookshop
jdbc.username=root
jdbc.password=1234

2.通过命名空间引用外部文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd
">
      <!--加载properties文件-->
     <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

3.配置属性

<!--配置数据源信息-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

外部命名空间标签的执行流程,如下:

  • 将自定义标签的约束与物理约束文件与网络约束名称的约束以键值对形式存储到一个spring.schemas文件里 , 该文件存储在类加载路径的META-INF里, Spring会自动加载到;

  • 将自定义命名空间的名称与自定义命名空间的处理器映射关系以键值对形式存在到一个叫spring.handlers文 件里, 该文件存储在类加载路径的META-INF里, Spring会自动加载到;

  • 准备好NamespaceHandler, 如果命名空间只有一个标签, 那么直接在parse方法中进行解析即可, 一般解析结 果就是注册该标签对应的BeanDefinition。如果命名空间里有多个标签, 那么可以在init方法中为每个标签都注 册一个BeanDefinitionParser, 在执行NamespaceHandler的parse方法时在分流给不同的 BeanDefinitionParser进行解析(重写doParse方法即可) 。

三:案例演示

        设想自己是一名架构师, 进行某一个框架与Spring的集成开发, 效果是通过一个指示标签, 向Spring容器中自动注入一个BeanPostProcessor

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/xmlSchema-instance"
xmlns:haohao="http://www.tangyuan.com/haohao"
xsi:schemaLocation="http://www.springframework.org/schema/beans         
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.tangyuan.com/haohao
http://www.tangyuan.com/haohao/haohao-annotation.xsd">
     <haohao:annotation-driven/>
</beans>

步骤分析:

1.确定命名空间名称、schema虚拟路径、标签名称;

2.编写schema约束文件haohao-annotation.xsd

3.在类加载路径下创建META-INF目录, 编写约束映射文件spring.schemas和处理器映射文件spring.handlers

4.编写命名空间处理器HaohaoNamespaceHandler, 在init方法中注册HaohaoBeanDefinitionParser

5.编写标签的解析器HaohaoBeanDefinitionParser, 在parse方法中注册HaohaoBeanPostProcessor

6.编写HaohaoBeanPostProcessor

========以上五步是框架开发者写的,以下是框架使用者写的

1.在applicationContext.xml配置文件中引入命名空间

2.在applicationContext.xml配置文件中使用自定义的标签

代码演示:

1.确定命名空间名称、schema虚拟路径、标签名称;

2.编写schema约束文件haohao-annotation.xsd

<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns="http://www.tangyuan.com/haohao"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.tangyuan.com/haohao">

    <xsd:element name="annotation-driven"></xsd:element>

</xsd:schema>

3.在类加载路径下创建META-INF目录, 编写约束映射文件spring.schemas和处理器映射文件spring.handlers

http\://www.tangyuan.com/haohao/haohao-annotation.xsd=com/tangyuan/haohao/config/haohao-annotation.xsd
http\://www.tangyuan.com/haohao=com.tangyuan.handlers.HaohaoNamespaceHandler

4.编写命名空间处理器HaohaoNamespaceHandler, 在init方法中注册HaohaoBeanDefinitionParser

package com.tangyuan.handlers;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class HaohaoNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        //初始化,一般情况下,一个名空间下有多个标签,会在init方法中为每一个标签注册一个标签解析器
        this.registerBeanDefinitionParser("annotation-driven",new HaohaoBeanDefinitionParser());
    }
}

5.编写标签的解析器HaohaoBeanDefinitionParser, 在parse方法中注册HaohaoBeanPostProcessor

package com.tangyuan.handlers;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

public class HaohaoBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        //注入一个BeanPostProcessor
        BeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.tangyuan.processor.HaohaoBeanPostProcessor");
        parserContext.getRegistry().registerBeanDefinition("haohaoBeanPostProessor",beanDefinition);
        return beanDefinition;
    }
}

6.编写HaohaoBeanPostProcessor

package com.tangyuan.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class HaohaoBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("HaohaoBeanPostProcessor执行....");
        return bean;
    }
}

7.在主xml文件引用

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:haohao="http://www.tangyuan.com/haohao"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd
       http://www.tangyuan.com/haohao
       http://www.tangyuan.com/haohao/haohao-annotation.xsd
">
  <!--使用自定义的命名空间标签-->
    <haohao:annotation-driven></haohao:annotation-driven>

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

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

相关文章

VScode连接本地Docker

一、安装VScode和Docker 1、vscode的安装 官网下载到最新的X64安装包&#xff0c;然后使用下述命令进行安装&#xff1a; dpkg -i code_1.73.1-1667967334_amd64.deb 安装成功之后&#xff0c;可以在应用的安装列表中查看到。 2、docker的安装 同上 二、创建docker的用户…

使用nginx临时搭建rtmp服务器

使用nginx临时搭建rtmp服务器 文章目录使用nginx临时搭建rtmp服务器系统环境搭建步骤RTMP服务验证由于需要研究rtmp协议交互方式及报数据格式&#xff0c;使用nginx临时搭建一个rtmp服务器&#xff0c;主要通过nginx的rtmp扩展模块实现接收RTMP推送的音视频流&#xff0c;同时提…

【C++】缺省参数

其实在C基础一文中已经介绍过了缺省参数&#xff0c;但是每次用这玩意都是很迷&#xff0c;今天趁着复习c知识&#xff0c;再来总结一下缺省参数。 &#x1f308;1.缺省参数知识图&#xff1a; 看来看去也就这么多的知识点&#xff0c;接下来就一一介绍一下&#xff1a; &…

prometheus监控微服务端口和主机存活

简介&#xff1a; BlackBox Exporter 顾名思义就是在应用程序的外部对其进行探测&#xff0c; 支持 HTTP、HTTPS、DNS、TCP、ICMP等方式对目标进行检测。 官方下载链接 https://github.com/prometheus/blackbox_exporter/releases/download/v0.21.1/blackbox_exporter-0.21.…

CRM管理系统软件哪家好?

规模不大的企业&#xff0c;往往抗风险能力较差、资金不足、员工也相对比较少&#xff0c;此时&#xff0c;客户资源&#xff0c;客户开发往往成为企业生存的基础。 对于企业&#xff0c;一款合适的CRM客户管理系统&#xff0c;绝对是小规模企业的必备工具&#xff0c;可以帮助…

自除数判断,除自身以外数组乘积,[ ]操作符,二维数组内存存储计算,有关进制转换与取数字每一位的问题

tips 1. 表达式求值的时候&#xff0c;首先当然是从左往右看&#xff0c;确定优先级&#xff08;只针对相邻操作符才有意义&#xff09;&#xff0c;相邻操作符按照优先级高低计算&#xff0c;如果&#xff08;相邻&#xff09;操作符的优先级相同&#xff08;也就是两个操作符…

4G低功耗摄像头模组如何快速唤醒拍照

对于应用在野外恶劣环境&#xff0c;无电无网络的情况下&#xff0c;需要一款能支持太阳能供电或者电池供电&#xff0c;不过前提是&#xff0c;功耗需要足够低&#xff0c;还需要能支持无线网络&#xff0c;能上传图片回到服务器&#xff0c;用于监测一些野外作业的数据&#…

Vue.set()的使用,以及对其进行深入解析

目录 Vue.set()使用 Vue.delete()的使用 Vue.set()方法原理解析 总结 Vue.set()使用 vue 在实例上添加新的属性的时候&#xff0c;该属性&#xff0c;并不是响应式的。同样删除某一属性的时候&#xff0c;也不会实时渲染到页面上。 比如&#xff1a; <p> 年龄&#x…

Python开发案例之用Python子进程关闭Excel自动化中的弹窗

利用Python进行Excel自动化操作的过程中&#xff0c;尤其是涉及VBA时&#xff0c;可能遇到消息框/弹窗&#xff08;MsgBox&#xff09;。此时需要人为响应&#xff0c;否则代码卡死直至超时 [^1] [^2]。根本的解决方法是VBA代码中不要出现类似弹窗&#xff0c;但有时我们无权修…

在专网建设场景,LoRa和NB的技术优劣对比

先说结论&#xff1a;运营商在大铺NB&#xff0c;LoRa更适用于专网。 对于某个企业或者组织的实际应用来说&#xff0c;最后很可能是nb做骨架&#xff0c;lora做补充&#xff0c;混合应用。除非是nb在覆盖继续完善做到无死角 其实&#xff0c;对于物联网复杂的应用场景来说&am…

国产的内网穿透工具也很优秀,这10款工具推荐正在寻找的你!

什么是内网穿透&#xff1f; 首先&#xff0c;我们生活中的网络从应用上可以分为内网和外网&#xff1b; 内网就是你自己的网络环境&#xff0c;就你自己能访问&#xff0c;比如你本地测试进行的localhost&#xff1b; 外网就不言而喻了&#xff0c;你看网页&#xff0c;视频…

利用vite创建vue3工程

目录 什么是vite 优势&#xff1a; 简单理解&#xff1a; 1、创建工程 2、进入工程目录&#xff0c;安装依赖 3、启动​编辑 什么是vite 官方创建的前端构建工具 优势&#xff1a; 1开发环境中&#xff0c;无需打包操作&#xff0c;可快速冷启动 2轻量快速的热重载 3真…

Word文件加密的方法有哪些?两种方法告诉你

日常生活工作中&#xff0c;我们经常会使用到Word文档。有时里面有些比较重要的内容&#xff0c;我们不想别人随便可以更改我们输入的内容、窥探我们的隐私&#xff0c;我们该怎么做&#xff1f;建议给你的word文件加密&#xff0c;这样就能更好保护我们的信息。 操作环境&…

C语言论坛系统[2023-01-03]

C语言论坛系统[2023-01-03] 论坛系统设计 课程说明 需要提交的内容包括两个部分。 第一部分&#xff0c;对代码功能的讲解。 课设要求最后每个同学录制一个讲解视频&#xff0c;对着自己代码的功能进行讲解。 讲解时&#xff0c;主要涉及一个几个标准步骤&#xff1a; 步骤一…

【实操篇】Linux定时任务调度

目录 ●crond任务调度 简要介绍 基本语法 常用选项 参数细节说明 典型案例 应用实例 ●crond任务调度 简要介绍&#xff1a; 任务调度&#xff0c;它是指系统在某个特定时间去执行的特定命令或程序。它分为两类&#xff0c;第一类为系统工作&#xff08;一些周…

自动驾驶数据集(一):KITTI数据集介绍

如有错误&#xff0c;恳请指出。 文章目录0. 数据集下载1. 标注数据label_22. 校准数据calib3. 点云数据velodyne4. 图像数据image_20. 数据集下载 KITTI数据集的下载地址&#xff1a;https://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark3d&#xff0c;下载…

redis集群简介

集群的概念 所谓的集群&#xff0c;就是通过添加服务器的数量&#xff0c;提供相同的服务&#xff0c;从而让服务器达到一个稳定、高效的状态。 1.1.1 使用redis集群的必要性 问题&#xff1a;我们已经部署好了redis&#xff0c;并且能启动一个redis&#xff0c;实现数据的读写…

鸿蒙 HDF 框架介绍

鸿蒙 HDF 框架介绍鸿蒙 HDF 框架介绍HDF 驱动框架框图HDF 驱动框架工作原理HDF 驱动框架工作原理框图&#xff1a;HDF 驱动加载过程分析HDF 驱动加载过程分析——驱动实现1HDF 驱动加载过程分析——驱动实现2HDF 驱动加载过程分析——获取驱动列表HDF 驱动加载过程分析——获取…

buu刷题记录

[ACTF新生赛2020]crypto-aes from Cryptodome.Cipher import AES import os import gmpy2 from flag import FLAG from Cryptodome.Util.number import *def main():keyos.urandom(2)*16ivos.urandom(16)print(bytes_to_long(key)^bytes_to_long(iv))aesAES.new(key,AES.MODE_…

第五章. 可视化数据分析图表—综合应用(双y轴,堆叠柱形图,颜色渐变饼形图,等高线图)

第五章. 可视化数据分析图 5.7 综合应用 1.双Y轴可视化数据分析图表的实现 &#xff08;柱形图折线图&#xff09; 双y轴&#xff0c;顾名思义就是两个y轴&#xff0c;可以通过双y轴看出发展情况的同时&#xff0c;还可以看到正常速度。 1).注意&#xff1a; add_subplot一定要…