SSM - Springboot - MyBatis-Plus 全栈体系(五)

news2025/1/21 8:59:02

第二章 SpringFramework

四、SpringIoC 实践和应用

2. 基于 XML 配置方式组件管理

2.5 实验五:高级特性:FactoryBean 特性和使用

2.5.1 FactoryBean 简介
  • FactoryBean 接口是Spring IoC容器实例化逻辑的可插拔性点。

  • 用于配置复杂的Bean对象,可以将创建过程存储在FactoryBean 的getObject方法!

  • FactoryBean<T> 接口提供三种方法:

    • T getObject(): 返回此工厂创建的对象的实例。该返回值会被存储到IoC容器!
    • boolean isSingleton(): 如果此 FactoryBean 返回单例,则返回 true ,否则返回 false 。此方法的默认实现返回 true (注意,lombok插件使用,可能影响效果)。
    • Class<?> getObjectType(): 返回 getObject() 方法返回的对象类型,如果事先不知道类型,则返回 null

在这里插入图片描述

2.5.2 FactoryBean 使用场景
  • 代理类的创建
  • 第三方框架整合
  • 复杂对象实例化等
2.5.3 Factorybean 应用
2.5.3.1 准备FactoryBean实现类
// 实现FactoryBean接口时需要指定泛型
// 泛型类型就是当前工厂要生产的对象的类型
public class HappyFactoryBean implements FactoryBean<HappyMachine> {
    
    private String machineName;
    
    public String getMachineName() {
        return machineName;
    }
    
    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }
    
    @Override
    public HappyMachine getObject() throws Exception {
    
        // 方法内部模拟创建、设置一个对象的复杂过程
        HappyMachine happyMachine = new HappyMachine();
    
        happyMachine.setMachineName(this.machineName);
    
        return happyMachine;
    }
    
    @Override
    public Class<?> getObjectType() {
    
        // 返回要生产的对象的类型
        return HappyMachine.class;
    }
}
2.5.3.2 配置FactoryBean实现类
<!-- FactoryBean机制 -->
<!-- 这个bean标签中class属性指定的是HappyFactoryBean,但是将来从这里获取的bean是HappyMachine对象 -->
<bean id="happyMachine7" class="com.alex.ioc.HappyFactoryBean">
    <!-- property标签仍然可以用来通过setXxx()方法给属性赋值 -->
    <property name="machineName" value="iceCreamMachine"/>
</bean>
2.5.3.3 测试读取FactoryBean和FactoryBean.getObject对象
@Test
public void testExperiment07()  {

    ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-bean-07.xml");

    //注意: 直接根据声明FactoryBean的id,获取的是getObject方法返回的对象
    HappyMachine happyMachine = iocContainer.getBean("happyMachine7",HappyMachine.class);
    System.out.println("happyMachine = " + happyMachine);

    //如果想要获取FactoryBean对象, 直接在id前添加&符号即可!  &happyMachine7 这是一种固定的约束
    Object bean = iocContainer.getBean("&happyMachine7");
    System.out.println("bean = " + bean);
}
2.5.4 FactoryBean和BeanFactory区别
  • FactoryBean 是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!是一种能够生产其他 Bean 的 Bean。FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean。因此,FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean。

  • 一般情况下,整合第三方框架,都是通过定义FactoryBean实现!!!

  • BeanFactory 是 Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为,例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等。BeanFactory 接口提供了访问 bean 的方式,例如 getBean() 方法获取指定的 bean 实例。它可以从不同的来源(例如 Mysql 数据库、XML 文件、Java 配置类等)获取 bean 定义,并将其转换为 bean 实例。同时,BeanFactory 还包含很多子类(例如,ApplicationContext 接口)提供了额外的强大功能。

  • 总的来说,FactoryBean 和 BeanFactory 的区别主要在于前者是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,而后者是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。

2.6 实验六:基于 XML 方式整合三层架构组件

2.6.1 需求分析
  • 搭建一个三层架构案例,模拟查询全部学生(学生表)信息,持久层使用JdbcTemplate和Druid技术,使用XML方式进行组件管理

在这里插入图片描述

2.6.2 数据库准备
create database studb;

use studb;

CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  gender VARCHAR(10) NOT NULL,
  age INT,
  class VARCHAR(50)
);

INSERT INTO students (id, name, gender, age, class)
VALUES
  (1, '张三', '男', 20, '高中一班'),
  (2, '李四', '男', 19, '高中二班'),
  (3, '王五', '女', 18, '高中一班'),
  (4, '赵六', '女', 20, '高中三班'),
  (5, '刘七', '男', 19, '高中二班'),
  (6, '陈八', '女', 18, '高中一班'),
  (7, '杨九', '男', 20, '高中三班'),
  (8, '吴十', '男', 19, '高中二班');
2.6.3 项目准备
2.6.3.1 项目创建
  • spring-xml-practice-02
2.6.3.2 依赖导入
<dependencies>
      <!--spring context依赖-->
      <!--当你引入SpringContext依赖之后,表示将Spring的基础依赖引入了-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>6.0.6</version>
      </dependency>

      <!-- 数据库驱动和连接池-->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.25</version>
      </dependency>

      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.2.8</version>
      </dependency>

      <!-- spring-jdbc -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>6.0.6</version>
      </dependency>

</dependencies> 
2.6.3.3 实体类准备
public class Student {

    private Integer id;
    private String name;
    private String gender;
    private Integer age;
    private String classes;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getClasses() {
        return classes;
    }

    public void setClasses(String classes) {
        this.classes = classes;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", classes='" + classes + '\'' +
                '}';
    }
}
2.6.4 JdbcTemplate技术讲解
  • 为了在特定领域帮助我们简化代码,Spring 封装了很多 『Template』形式的模板类。例如:RedisTemplate、RestTemplate 等等,包括我们今天要学习的 JdbcTemplate。
  • jdbc.properties :提取数据库连接信息
alex.url=jdbc:mysql://localhost:3306/studb
alex.driver=com.mysql.cj.jdbc.Driver
alex.username=root
alex.password=root
  • springioc配置文件
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <!-- 导入外部属性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />

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

    <!-- 配置 JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!-- 装配数据源 -->
        <property name="dataSource" ref="druidDataSource"/>
    </bean>
    
</beans>
  • 基于jdbcTemplate的CRUD使用
public class JdbcTemplateTest {


    /**
     * 使用jdbcTemplate进行DML动作
     */
    @Test
    public void testDML(){

        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-ioc.xml");

        JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);

        //TODO 执行插入一条学员数据
        String sql = "insert into students (id,name,gender,age,class) values (?,?,?,?,?);";
    /*
        参数1: sql语句
        参数2: 可变参数,占位符的值
     */
        int rows = jdbcTemplate.update(sql, 9,"十一", "男", 18, "二年三班");

        System.out.println("rows = " + rows);

    }


    /**
     * 查询单条实体对象
     *   public class Student {
     *     private Integer id;
     *     private String name;
     *     private String gender;
     *     private Integer age;
     *     private String classes;
     */
    @Test
    public void testDQLForPojo(){

        String sql = "select id , name , age , gender , class as classes from students where id = ? ;";

        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-ioc.xml");

        JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);

        //根据id查询
        Student student = jdbcTemplate.queryForObject(sql,  (rs, rowNum) -> {
            //自己处理结果映射
            Student stu = new Student();
            stu.setId(rs.getInt("id"));
            stu.setName(rs.getString("name"));
            stu.setAge(rs.getInt("age"));
            stu.setGender(rs.getString("gender"));
            stu.setClasses(rs.getString("classes"));
            return stu;
        }, 2);

        System.out.println("student = " + student);
    }



    /**
     * 查询实体类集合
     */
    @Test
    public void testDQLForListPojo(){

        String sql = "select id , name , age , gender , class as classes from students  ;";

        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-ioc.xml");

        JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);
    /*
        query可以返回集合!
        BeanPropertyRowMapper就是封装好RowMapper的实现,要求属性名和列名相同即可
     */
        List<Student> studentList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));

        System.out.println("studentList = " + studentList);
    }

}
2.6.5 三层架构搭建和实现
2.6.5.1 持久层
//接口
public interface StudentDao {

    /**
     * 查询全部学生数据
     * @return
     */
    List<Student> queryAll();
}

//实现类
public class StudentDaoImpl implements StudentDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 查询全部学生数据
     * @return
     */
    @Override
    public List<Student> queryAll() {

        String sql = "select id , name , age , gender , class as classes from students ;";

        /*
          query可以返回集合!
          BeanPropertyRowMapper就是封装好RowMapper的实现,要求属性名和列名相同即可
         */
        List<Student> studentList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));

        return studentList;
   }
}
2.6.5.2 业务层
//接口
public interface StudentService {

    /**
     * 查询全部学员业务
     * @return
     */
    List<Student> findAll();

}

//实现类
public class StudentServiceImpl implements StudentService {
    
    private StudentDao studentDao;

    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    /**
     * 查询全部学员业务
     * @return
     */
    @Override
    public List<Student> findAll() {
        
        List<Student> studentList =  studentDao.queryAll();
        
        return studentList;
    }
}
2.6.5.3 表述层
public class StudentController {
    
    private StudentService studentService;

    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    
    public void findAll(){
       List<Student> studentList =  studentService.findAll();
        System.out.println("studentList = " + studentList);
    }
}
2.6.6 三层架构IoC配置
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <!-- 导入外部属性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />

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

    <!-- 配置 JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!-- 装配数据源 -->
        <property name="dataSource" ref="druidDataSource"/>
    </bean>


    <bean id="studentDao" class="com.alex.dao.impl.StudentDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <bean id="studentService" class="com.alex.service.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao" />
    </bean>

    <bean id="studentController" class="com.alex.controller.StudentController">
        <property name="studentService" ref="studentService" />
    </bean>

</beans>
2.6.7 运行测试
public class ControllerTest {

    @Test
    public void testRun(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-ioc.xml");
        StudentController studentController = applicationContext.getBean(StudentController.class);
        studentController.findAll();
    }
2.6.8 XMLIoC方式问题总结
  • 注入的属性必须添加setter方法、代码结构乱!
  • 配置文件和Java代码分离、编写不是很方便!
  • XML配置文件解析效率低

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

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

相关文章

前端list.push,封装多个对象

js var fruit [apple, banana];fruit.push(pear);console.log(fruit); // [apple, banana, pear]现在为对象 data1:{addUser: 1,editUser: 1,addTime: null,editTime: 1527410579000,userId: 3,systemNo: mc,userName: zengzhuo,userPassword: e10adc3949ba59abbe56e057f20f88…

Qt点亮I.MX6U开发板的一个LED

本篇开始将会介绍与开发版相关的Qt项目&#xff0c;首先从点亮一个LED开始。I.MX6U和STM32MP157的相关信息都会用到&#xff0c;但是后期还是将I.MX6U的学习作为重点。当然其他开发版的开发也可以参考本博文。 文章目录 1. Qt是如何操控开发板上的一个LED2. 出厂内核设备树中注…

linux修改最大线程数却未生效的原因

可能是没有重新对新文件进行编译 更改一个进程所能创建的最大进程数之前 更改一个进程所能创建的最大进程数之后 测试代码 #include <iostream> #include <unistd.h> #include <sys/wait.h> #include <string.h> #include <stdio.h> #include…

学生信息系统(python实现)

#codingutf-8 import os.path filenamestudent.txtdef menm():#菜单界面print(学生管理系统)print(-----------------------------功能菜单-----------------------------)print(\t\t\t\t\t\t1.录入学生信息)print(\t\t\t\t\t\t2.查找学生信息)print(\t\t\t\t\t\t3.删除学生信息…

合宙Air724UG LuatOS-Air LVGL API控件-图片(Gif)

图片&#xff08;Gif&#xff09; GIF图片显示&#xff0c;core版本号要>3211 示例代码 方法一 -- 创建GIF图片控件 glvgl.gif_create(lvgl.scr_act()) -- 设置显示的GIF图像 lvgl.gif_set_src(g,"/lua/test.gif") -- gif图片居中 lvgl.obj_align(g, nil, lvgl…

软件测试行业35岁职场魔咒,你准备怎么应对?

以前就流传一种说法“IT行业职场35岁危机”&#xff0c;那时我半信半疑。 或许那时觉得还离我比较遥远&#xff0c;也或许那时每天都重复着996&#xff0c;工作上的任务已经应接不暇&#xff0c;每天都处在忙碌中&#xff0c;也没精力花时间去过多思考这个问题。休息的时候能好…

机器学习实战-系列教程7:SVM分类实战2线性SVM(鸢尾花数据集/软间隔/线性SVM/非线性SVM/scikit-learn框架)项目实战、代码解读

&#x1f308;&#x1f308;&#x1f308;机器学习 实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 SVM分类实战1之简单SVM分类 SVM分类实战2线性SVM SVM分类实战3非线性SVM 3、不同软间隔C值 3.1 数据标准化的影响 如图左边是没…

GLSL ES着色器 精度限定字

目录 前言 WebGL支持的三种精度 数据类型的默认精度 float类型没有默认精度 预处理指令 在GLSL ES中常用的三种预处理指令。 预定义的内置宏 前言 GLSL ES新引入了精度限定字&#xff0c;目的是帮助着色器程序提高运行效率&#xff0c;削减内存开支。顾名思义&#xf…

Kafka3.0.0版本——消费者(自动提交 offset)

目录 一、自动提交offset的相关参数二、消费者&#xff08;自动提交 offset&#xff09;代码示例 一、自动提交offset的相关参数 官网文档 参数解释 参数描述enable.auto.commi默认值为 true&#xff0c;消费者会自动周期性地向服务器提交偏移量。auto.commit.interval.ms如果…

《TCP/IP网络编程》阅读笔记--I/O复用

1--基于I/O复用的服务器 多进程服务器端具有以下缺点&#xff1a;当有多个客户端发起连接请求时&#xff0c;就会创建多个进程来分别处理客户端的请求&#xff0c;创建多个进程往往需要付出巨大的代价&#xff1b; I/O复用的服务器端可以减少进程数&#xff0c;无论连接多少个客…

Ubuntu22.04_如何调试ROS2_humble的源代码

这里的源码&#xff0c;是指的ros2 humble的官方源码。如果是自己手撸的节点或相关源码&#xff0c;请参考本人以前的贴子&#xff0c; Ubuntu20.04vscode快速调试ROS通用程序_ubuntu20.04vscode那个版本和ros 兼容_高精度计算机视觉的博客-CSDN博客 Ubuntu20.04&#xff0b;…

【pygame】01 pygame制作游戏的最小系统

这次使用sublimepython进行pygame的游戏开发&#xff0c;目的是学习使用python的基本操作和常用模块 添加一个文件夹到工程 最小系统 import pygame import sys ##导入sys模块 主要是为了 exit函数 from pygame.locals import * #导入一些常用的函数和常量pygame.init() …

计算机网络第四章——网络层(上)

提示&#xff1a;朝碧海而暮苍梧,睹青天而攀白日 文章目录 网络层是路由器的最高层次&#xff0c;通过网络层就可以将各个设备连接到一起&#xff0c;从而实现这两个主机的数据通信和资源共享&#xff0c;之前学的数据链路层和物理层也是将两端连接起来&#xff0c;但是却没有网…

C语言——指针进阶(2)

继续上次的指针&#xff0c;想起来还有指针的内容还没有更新完&#xff0c;今天来补上之前的内容&#xff0c;上次我们讲了函数指针&#xff0c;并且使用它来实现一些功能&#xff0c;今天我们就讲一讲函数指针数组等内容&#xff0c;废话不多说&#xff0c;我们开始今天的学习…

ESP32蓝牙主从站模式:主站发送,从站接收,同时附加简单通信协议

主站发送:WXAiBj,六个字符 蓝牙模式是一个字符一个字符发送 主站和从站设置通信协议 使得六个字符一句话完整接收,同时打印出接收完成信息 硬件电路连接如下: 主从站为两个ESP32,只使用了其中的蓝牙功能 代码如下: 主站: //主机模式 #include <Arduino.h> …

ARM指令集--数据处理指令

数据处理指令&#xff1a;数学运算&#xff0c;逻辑运算 立即数 立即数的本质 就是包含在指令当中的数&#xff0c;属于指令的一部分 立即数的优点&#xff1a;取指的时候就可以将其读取到CPU&#xff0c;不用单独去内存读取&#xff0c;速度快 立即数的缺点&#xff1a;不…

vue学习之内容渲染

内容渲染 创建 demo2.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…

敏捷项目管理完整流程及实践管理方法

​Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交付最大价值。 Leangoo领歌是一款永久免费的专业敏捷研发管理工具&#xff0c;提供敏捷研发解决方案&#xff0c;解决研发痛点&#xff0c;打造成功…

学习机器学习需要哪些数学知识?

作为一门以数据及其模型为 研究对象的学科&#xff0c;优化模型、分析模型性能等都需要数学手段的帮助。和其他学科一样&#xff0c;数学 可以帮我们更清晰地描述和理解机器学习算法&#xff0c;也可以从理论上证明算法的有效性&#xff0c;是机器学习中必不可少的一环。 1 向…