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

news2024/11/18 17:39:41

第二章 SpringFramework

四、SpringIoC 实践和应用

4. 基于 配置类 方式管理 Bean

4.4 实验三:高级特性:@Bean 注解细节

4.4.1 @Bean 生成 BeanName 问题
  • @Bean 注解源码:
public @interface Bean {
    //前两个注解可以指定Bean的标识
    @AliasFor("name")
    String[] value() default {};
    @AliasFor("value")
    String[] name() default {};

    //autowireCandidate 属性来指示该 Bean 是否候选用于自动装配。
    //autowireCandidate 属性默认值为 true,表示该 Bean 是一个默认的装配目标,
    //可被候选用于自动装配。如果将 autowireCandidate 属性设置为 false,则说明该 Bean 不是默认的装配目标,不会被候选用于自动装配。
    boolean autowireCandidate() default true;

    //指定初始化方法
    String initMethod() default "";
    //指定销毁方法
    String destroyMethod() default "(inferred)";
}
  • 指定@Bean 的名称:
@Configuration
public class AppConfig {

  @Bean("myThing") //指定名称
  public Thing thing() {
    return new Thing();
  }
}
  • @Bean 注释注释方法。使用此方法在指定为方法返回值的类型的 ApplicationContext 中注册 Bean 定义。缺省情况下,Bean 名称与方法名称相同。下面的示例演示 @Bean 方法声明:
@Configuration
public class AppConfig {

  @Bean
  public TransferServiceImpl transferService() {
    return new TransferServiceImpl();
  }
}
  • 前面的配置完全等同于下面的 Spring XML:
<beans>
  <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
4.4.2 @Bean 初始化和销毁方法指定
  • @Bean 注解支持指定任意初始化和销毁回调方法,非常类似于 Spring XML 在 bean 元素上的 init-method 和 destroy-method 属性,如以下示例所示:
public class BeanOne {

  public void init() {
    // initialization logic
  }
}

public class BeanTwo {

  public void cleanup() {
    // destruction logic
  }
}

@Configuration
public class AppConfig {

  @Bean(initMethod = "init")
  public BeanOne beanOne() {
    return new BeanOne();
  }

  @Bean(destroyMethod = "cleanup")
  public BeanTwo beanTwo() {
    return new BeanTwo();
  }
}
4.4.3 @Bean Scope 作用域
  • 可以指定使用 @Bean 注释定义的 bean 应具有特定范围。您可以使用在 Bean 作用域部分中指定的任何标准作用域。

  • 默认作用域为 singleton ,但可以使用 @Scope 注释覆盖此范围,如以下示例所示:

@Configuration
public class MyConfiguration {

  @Bean
  @Scope("prototype")
  public Encryptor encryptor() {
    // ...
  }
}
4.4.4 @Bean 方法之间依赖
4.4.4.1 准备组件
public class HappyMachine {

    private String machineName;

    public String getMachineName() {
        return machineName;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }
}
public class HappyComponent {
    //引用新组件
    private HappyMachine happyMachine;

    public HappyMachine getHappyMachine() {
        return happyMachine;
    }

    public void setHappyMachine(HappyMachine happyMachine) {
        this.happyMachine = happyMachine;
    }

    public void doWork() {
        System.out.println("HappyComponent.doWork");
    }

}
4.4.4.2 Java 配置类实现:
  • 方案 1:直接调用方法返回 Bean 实例:在一个 @Bean 方法中直接调用其他 @Bean 方法来获取 Bean 实例,虽然是方法调用,也是通过 IoC 容器获取对应的 Bean,例如:
@Configuration
public class JavaConfig {

    @Bean
    public HappyMachine happyMachine(){
        return new HappyMachine();
    }

    @Bean
    public HappyComponent happyComponent(){
        HappyComponent happyComponent = new HappyComponent();
        //直接调用方法即可!
        happyComponent.setHappyMachine(happyMachine());
        return happyComponent;
    }

}
  • 方案 2:参数引用法:通过方法参数传递 Bean 实例的引用来解决 Bean 实例之间的依赖关系,例如:
package com.alex.config;

import com.alex.ioc.HappyComponent;
import com.alex.ioc.HappyMachine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * projectName: com.alex.config
 * description: 配置HappyComponent和HappyMachine关系
 */

@Configuration
public class JavaConfig {

    @Bean
    public HappyMachine happyMachine(){
        return new HappyMachine();
    }

    /**
     * 可以直接在形参列表接收IoC容器中的Bean!
     *    情况1: 直接指定类型即可
     *    情况2: 如果有多个bean,(HappyMachine 名称 ) 形参名称等于要指定的bean名称!
     *           例如:
     *               @Bean
     *               public Foo foo1(){
     *                   return new Foo();
     *               }
     *               @Bean
     *               public Foo foo2(){
     *                   return new Foo()
     *               }
     *               @Bean
     *               public Component component(Foo foo1 / foo2 通过此处指定引入的bean)
     */
    @Bean
    public HappyComponent happyComponent(HappyMachine happyMachine){
        HappyComponent happyComponent = new HappyComponent();
        //赋值
        happyComponent.setHappyMachine(happyMachine);
        return happyComponent;
    }

}

4.5 实验四:高级特性:@Import 扩展

  • @Import 注释允许从另一个配置类加载 @Bean 定义,如以下示例所示:
@Configuration
public class ConfigA {

  @Bean
  public A a() {
    return new A();
  }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {

  @Bean
  public B b() {
    return new B();
  }
}
  • 现在,在实例化上下文时不需要同时指定 ConfigA.class 和 ConfigB.class ,只需显式提供 ConfigB ,如以下示例所示:
public static void main(String[] args) {
  ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);

  // now both beans A and B will be available...
  A a = ctx.getBean(A.class);
  B b = ctx.getBean(B.class);
}
  • 此方法简化了容器实例化,因为只需要处理一个类,而不是要求在构造期间记住可能大量的 @Configuration 类。

4.6 实验五:基于注解 + 配置类方式整合三层架构组件

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

在这里插入图片描述

4.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, '高中二班');
4.6.3 项目准备
4.6.3.1 项目创建
  • spring-java-practice-06
4.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>

      <dependency>
            <groupId>jakarta.annotation</groupId>
            <artifactId>jakarta.annotation-api</artifactId>
            <version>2.1.1</version>
       </dependency>

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

</dependencies>
4.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 + '\'' +
                '}';
    }
}
4.6.4 三层架构搭建和实现
4.6.4.1 持久层
//接口
public interface StudentDao {

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

//实现类
@Repository
public class StudentDaoImpl implements StudentDao {

    @Autowired
    private 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;
    }
}
4.6.4.2 业务层
//接口
public interface StudentService {

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

}

//实现类
@Service
public class StudentServiceImpl  implements StudentService {

    @Autowired
    private StudentDao studentDao;

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

        List<Student> studentList =  studentDao.queryAll();

        return studentList;
    }
}
4.6.4.3 表述层
@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    public void findAll(){
       List<Student> studentList =  studentService.findAll();
        System.out.println("studentList = " + studentList);
    }
}
4.6.5 三层架构 IoC 配置类
@Configuration
@ComponentScan(basePackages = "com.alex")
@PropertySource("classpath:jdbc.properties")
public class JavaConfig {

    @Value("${alex.url}")
    private String url;
    @Value("${alex.driver}")
    private String driver;
    @Value("${alex.username}")
    private String username;
    @Value("${alex.password}")
    private String password;

    @Bean(destroyMethod = "close")
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

}
4.6.6 运行测试
public class ControllerTest {

    @Test
    public void testRun(){

        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(JavaConfig.class);

        StudentController studentController = applicationContext.getBean(StudentController.class);

        studentController.findAll();

    }
}
4.6.7 注解+配置类 IoC 方式总结
  • 完全摒弃了 XML 配置文件
  • 自定义类使用 IoC 和 DI 注解标记
  • 第三方类使用配置类声明方法+@Bean 方式处理
  • 完全注解方式(配置类+注解)是现在主流配置方式

5. 三种配置方式总结

5.1 XML 方式配置总结

  • 所有内容写到 xml 格式配置文件中
  • 声明 bean 通过<bean 标签
  • <bean 标签包含基本信息(id,class)和属性信息 <property name value / ref
  • 引入外部的 properties 文件可以通过<context:property-placeholder
  • IoC 具体容器实现选择 ClassPathXmlApplicationContext 对象

5.2 XML+注解方式配置总结

  • 注解负责标记 IoC 的类和进行属性装配
  • xml 文件依然需要,需要通过<context:component-scan 标签指定注解范围
  • 标记 IoC 注解:@Component,@Service,@Controller,@Repository
  • 标记 DI 注解:@Autowired @Qualifier @Resource @Value
  • IoC 具体容器实现选择 ClassPathXmlApplicationContext 对象

5.3 完全注解方式配置总结

  • 完全注解方式指的是去掉 xml 文件,使用配置类 + 注解实现
  • xml 文件替换成使用@Configuration 注解标记的类
  • 标记 IoC 注解:@Component,@Service,@Controller,@Repository
  • 标记 DI 注解:@Autowired @Qualifier @Resource @Value
  • <context:component-scan 标签指定注解范围使用@ComponentScan(basePackages = {“com.alex.components”})替代
  • <context:property-placeholder 引入外部配置文件使用@PropertySource({“classpath:application.properties”,“classpath:jdbc.properties”})替代
  • <bean 标签使用@Bean 注解和方法实现
  • IoC 具体容器实现选择 AnnotationConfigApplicationContext 对象

6. 整合 Spring5-Test5 搭建测试环境

6.1 整合测试环境作用

  • 好处 1:不需要自己创建 IOC 容器对象了
  • 好处 2:任何需要的 bean 都可以在测试类中直接享受自动装配

6.2 导入相关依赖

<!--junit5测试-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.3.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>6.0.6</version>
    <scope>test</scope>
</dependency>

6.3 整合测试注解使用

//@SpringJUnitConfig(locations = {"classpath:spring-context.xml"})  //指定配置文件xml
@SpringJUnitConfig(value = {BeanConfig.class})  //指定配置类
public class Junit5IntegrationTest {

    @Autowired
    private User user;

    @Test
    public void testJunit5() {
        System.out.println(user);
    }
}

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

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

相关文章

【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs Transformers) 的介绍合集(六)

文章目录 一、Co-Scale Conv-attentional Image Transformer&#xff08;CoaT&#xff09;二、Pyramid Vision Transformer v2(PVTv2)三、Class-Attention in Image Transformers&#xff08;CaiT&#xff09;四、PoolFormer五、ScaleNet六、VoVNet七、Siamese U-Net八、Single…

MT4和MT5的共同点,anzo capital昂首资本说一个,没人有意见吧

相信很多交易者对MT4和MT5都不会陌生&#xff0c;但您了解他们背后之间的关系吗?今天anzo capital昂首资本就和各位交易者一起聊聊&#xff0c;没人有意见的MT4和MT5的共同点。 其实谈起MT4和MT5&#xff0c;就不得不聊聊他们背后的公司MetaQuotes&#xff0c;MetaQuotes 是…

家政小程序源码家政预约小程序独立版,家政上门预约,功能强大

家政服务行业作为一个相对传统的行业&#xff0c;随着互联网的发展迅速&#xff0c;和用户群体的改变&#xff0c;家政服务公司也需要改变一下经营思路了&#xff0c;否则未来很难满足新一代用户群体的个性化需求。 核心功能&#xff1a; 1、师傅(服务人员)入驻&#xff1a;家…

IDEA怎么将CRLF转化为LF

执行命令&#xff1a; git config --global core.autocrlf input 或者使用IDEA的自动提交的修复

2023 Google开发者大会:你了解机器学习的新动向吗?

目录 0 年度科技盛会1 生成式机器学习2 无障碍游戏体验3 跨平台机器学习总结 0 年度科技盛会 2023Google开发者大会在上海浦东举办&#xff0c;为开发者和科技爱好者们带来新技术、新产品、新动向 可能很多同学对Google 开发者大会还不熟悉&#xff0c;Google 开发者大会是 G…

异步FIFO设计

1 FIFO简介 FIFO的本质是RAM&#xff0c;具有先进先出的特性。 FIFO的基本使用原则&#xff1a;空时不能读&#xff0c;满时不能写 FIFO的两个重要参数&#xff1a;宽度和深度 FIFO的两种类型&#xff1a; 同步FIFO&#xff1a;读写时钟相同&#xff0c;通常用来做数据缓存…

医疗领域超低温监控,你了解吗?

超低温冰箱在医疗保健领域中扮演着不可或缺的角色。它们被广泛用于存储生物样本、药物和疫苗等温度敏感的医疗物品&#xff0c;以确保这些关键资源的质量和有效性。 然而&#xff0c;温度波动和不稳定性可能会对这些物品造成严重损害&#xff0c;甚至威胁患者的生命。为了应对这…

对话泛微:产业数字化时代,我们需要怎样的OA?

在泛微诞生以后的十年&#xff0c;恰是OA系统的大规模突破。十年间&#xff0c;上百家OA企业的诞生直接将市场推向了鼎盛期。而后又迎来了移动互联网风口&#xff0c;在互联网厂商的冲击之下&#xff0c;传统OA在不断进击的同时&#xff0c;还要进行自我蜕变&#xff0c;成为“…

ppt录制在哪?实用技巧分享!

在现代演示和培训中&#xff0c;PPT演示已经成为越来越流行的一种交流方式。而录制ppt也成为了很多商务演讲、教学讲解、产品演示等场合的必备技能。本文将为您介绍两种常见的ppt录制方式&#xff0c;帮助您轻松录制ppt演示的过程。 ppt录制在哪&#xff1f; ppt是一款流行的演…

操作系统Deepin DTK顺利适配Qt6,从而提供更高效开发体验

据了解&#xff0c;当前deepin DTK(Development ToolKit)已经在近日顺利适配Qt6 (6.4.2)&#xff0c;从而实现全面升级。 据悉&#xff0c;DTK作为 deepin 基于Qt开发的一整套通用开发框架&#xff0c;并且是deepin操作系统中的核心位置。    Multiable万达宝ERP(www.multi…

打败全国百分之99.99的模板方法模式讲解

目录 背景&#xff1a;模板方法定义&#xff1a;步骤&#xff1a;初始版&#xff1a; 每个人都抄卷子&#xff0c;然后抄完写自己的答案第一版&#xff1a;将试卷的题抽象出来第二版&#xff1a;将每个人回答的部分抽象出来第三版&#xff1a;将答题步骤封装出来&#xff08;这…

lenovo联想Legion Y9000P IRX8H 2023款(82WQ)原装出厂Windows11系统

联想拯救者笔记本电脑原厂系统自带网卡、显卡、声卡等所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 链接&#xff1a;https://pan.baidu.com/s/1YBji_oh7xOkq-NxnS8Mm8g?pwdn17o 提取码&#xff1a;n17o 所需要工具&#xff1a;16G或以上的U盘 文件…

el-table 列背景色渐变

最初的想法是&#xff0c;给每一行添加背景色&#xff0c;逐行递减透明度&#xff0c;发现结果比较突兀&#xff0c;效果如下&#xff1a; 如果有需要这种样式的&#xff0c;代码如下&#xff1a; <template><div><el-table:data"tableData":heade…

小麦苗GreenPlum学习大纲

腾讯文档 课程文档内容如下&#xff1a; 小麦苗GreenPlum课程公开课-- 数据库通用学习路线、答疑、培训、考证等&#xff1a;https://docs.qq.com/doc/p/b65bcd7647a9974a94b97fb06d04a089c25a7f0c 小麦苗GreenPlum课程第0节-- 数据库简介、分类、发展、流行度排名等&#xf…

Docker容器化技术(从零学会Docker)

文章目录 前言一、初识Docker1.初识Docker-Docker概述2.初识Docker-安装Docker3.初识Docker-Docker架构4.初识Docker-配置镜像加速器 二、Docker命令1.Docker命令-服务相关命令2.Docker命令-镜像相关命令3.Docker命令-容器相关命令 三、Docker容器的数据卷1.Docker容器数据卷-数…

Python:函数定义的参数

相关阅读 Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 函数定义就是定义一个用户自定义的函数对象&#xff0c;它的语法的BNF范式如下所示&#xff0c;有关BNF范式的规则&#xff0c;可以参考之前的文章。 funcdef …

asp.net+sqlserver+c#教师工作量计算系统

本课题主要是解决工作量管理管理中的日常中涉及到的问题&#xff0c;目标是使工作量在管理上做到数据的信息化、快速化。 系统在实现上应至少具有如下功能&#xff1a; (1)教师信息管理 该模块包括教师信息的添加、修改。 (2)个人信息 该模块是对用户登录系统后对自己信息的修改…

C-结构体

目录 结构体 定义结构体 第一种方式 定义的同时定义变量名 第三种方式 赋值和初始化 如何取出结构体成员 结构体变量&#xff0c;结构体指针作为函数参数进行传递 结构体运算 结构体 形成了一个新的数据类型 定义结构体 第一种方式 定义一个新的数据类型&#xf…

Unity - Shader Compiled Log

文章目录 吐槽开启 Log Shader Compilation实践资源准备Build ABTesting ScriptShader Compiled Log Project 吐槽 先说一下&#xff0c;最近几天前&#xff0c;纷纷看到 unity install fee 的天才收费方案 真的忍不住吐槽&#xff0c;我只想说&#xff1a; “no zuo no die”…

旋转框/微调按钮的基类--QAbstractSpinBox 类

1、 QAbstractSpinBox 类是 QWidget 类的直接子类&#xff0c;虽然该类不是抽象类&#xff0c;但该类并未提供实 际的功能&#xff0c;仅为旋转框提供了一些外观的形式以及需要子类实现了成员&#xff0c; 也就是说点击微调按钮的上/下按钮&#xff0c;不会使其中的数值有变化。…