SpringBoot第二天

news2025/1/17 15:27:16

Bean管理

Bean扫描

在Spring中,Bean的扫描有两种写法

第一种是在xml配置文件中用标签扫描

<context:component-scan basepackage="com.cacb"/>

第二种是是注解扫描

@ComponentScan(basePackages="com.cacb")

 而在SpringBoot中,我们在启动类中使用了

@SpringBootApplication

注解,该注解实际上包含如下注解

故只要调用该注解Spring就能扫描启动类所在的包及其子包中的Bean,在我们使用时就实现了自动扫描,同时我们也应注意所有的Bean应该放在启动类所在的包及其子包中。

Bean注册

如果要注册的Bean来自第三方(不是自定义的),是无法使用@Component及衍生注解声明Bean的,可以使用如下两个注解

@Bean

譬如,我们在一个jar包中有一个实体类Book,需要在当前工程中导入Book实体,首先我们就需要在启动类中使用@Bean注解来注入Book对象

@SpringBootApplication
public class SpringBootMybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootMybatisApplication.class, args);
	}

    
    @Bean
    public Book book(){
        return new Book();
    }

}

但是这种方法需要在启动类中注解,不推荐,更好的方法是单独创建一个配置类来集中管理注册第三方Bean,该配置类需要在启动类同一个包及其子包中,并且要有@Configuration注解

@Configuration
public class CommonConfig {
    @Bean
    public Book book(){
        return new Book();
    }
}

如果需要改名,例如,要将Book对象名改为user,可以在Bean注释后更改(默认对象名为方法名):

    @Bean("user")
    public Book book(){
        return new Book();
    }

如果一个第三方对象内需要注入另一个第三方对象,可以在参数内自动注入,如下例在BookStore中注入Book:

    @Bean
    public Book book(){
        return new Book();
    }
    
    @Bean
    public BookStore bookstore(Book book){
        return new BookStore();
    }

@Import 

导入配置类

 例如,上文所写的CommonConfig不与启动类放在同一个包中,启动类就无法自动扫描到该配置类,此时就需要在启动类中使用@Import来完成手动注解

@SpringBootApplication
@Import(CommonConfig.class)
public class SpringBootMybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootMybatisApplication.class, args);
	}

}

注:如果有多个配置类需要注解,可以使用{}数组的形式来完成注解,同时,也可以通过导入ImportSelector接口来完成该工作。 

导入ImportSelector接口实现类

例如此时,config文件与启动类不在同一个文件,我们也可以通过导入ImportSelector接口实现类来手动注解。

首先我们需要制作一个ImportSelector接口实现类

public class CommonImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.cacb.config.CommonConfig"};
    }
}

然后再去启动类中使用@Import注解来完成手动注解

@SpringBootApplication
@Import(CommonImportSelector.class)
public class SpringBootMybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootMybatisApplication.class, args);
	}

}

当然,需要注入的Bean一般是从配置文件中读取的,方法如下,先构建配置文件 

 注:每行指书写一个Bean的全类名

com.cacb.config.CommonConfig

然后去接口实现类中加载配置文件

public class CommonImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        List<String> imports = new ArrayList<>();
        InputStream is = CommonImportSelector.class.getClassLoader().getResourceAsStream("common.imports");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        try {
            while ((line = br.readLine()) != null){
                imports.add(line);
            }
        } catch (IOException e){
            throw new RuntimeException(e);
        } finally {
            if(br != null){
                try {
                    br.close();
                } catch (IOException e){
                    throw new RuntimeException(e);
                }
            }
        }
        return imports.toArray(new String[0]);
    }
}

 组合类注解@EnableXxxx注解封装@Import注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(CommonImportSelector.class)
public @interface EnableCommonConfig {
}

完成后就可以在启动类中使用@EnableCommonConfig注解来代替@Import注解使用

@SpringBootApplication
@EnableCommonConfig
public class SpringBootMybatisApplication {

注册条件

SpringBoot提供了设置注册生效条件的注解@Conditional

自动配置原理 

自动配置

遵循约定大于配置的原则,在boot程序启动后,起步依赖中的一些Bean对象会自动注入到IOC容器

程序引入spring-boot-starter-web起步依赖,启动后,会自动往IOC容器中注入DispatcherServlet

在主启动类上添加了SpringBootApplication注解,这个注解组合了EnableAutoConfiguration注解

EnableAutoConfiguration注解又组合了Import注解,导入了AutoConfigurationImportSelector类

实现selectImports方法,这个方法经过多层调用,最终会读取META-INF目录下的后缀名为imports的文件,boot2.7以前的版本读取的是spring.factories文件

读取到imports文件中的全类名之后,会解析注册条件,也就是@Conditional及其衍生注解,把满足注册条件的Bean对象自动注入到IOC容器中

自定义starter

以Mybatisstarter为例

我们需要构建两个模块

在自动配置模块中首先要导入相应依赖坐标

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>3.2.2</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jdbc</artifactId>
      <version>3.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.14</version>

    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>3.0.3</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

然后提供自动配置类

@AutoConfiguration
public class MyBatisAutoConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(BeanFactory beanFactory){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //扫描的包:启动类所在的包及其子包
        List<String> packages =  AutoConfigurationPackages.get(beanFactory);
        String p = packages.get(0);
        mapperScannerConfigurer.setBasePackage(p);

        //扫描的注解
        mapperScannerConfigurer.setAnnotationClass(Mapper.class);
        return mapperScannerConfigurer;
    }
}

自建import文件,并将自动配置类完整路径写入

 注意imports文件存储路径一定要在META-INF.spring下

com.cacb.config.MyBatisAutoConfig

下面开始配置stater模块,该模块只需要导入相应坐标,故src文件可以直接删除掉

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>3.2.2</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jdbc</artifactId>
      <version>3.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.14</version>

    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>3.0.3</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

最重要的是导入我们写的自动装配模块,最好也要将自装配模块所依赖的坐标一并导入 

 

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

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

相关文章

张维迎《博弈与社会》威胁与承诺(4)宪政与民主

有限政府 动态博弈理论对我们理解民主与法治具有重要的意义。 自人类进入文明时代以来&#xff0c;政府就是社会博弈重要的参与人。任何社会要有效运行&#xff0c;都需要赋予政府一些自由裁量权。但如果政府的自由裁量权太大&#xff0c;政府官员为所欲为&#xff0c;不仅老百…

Jetson AGX Orin安装Anaconda,Cuda,Cudnn,pytorch,Tensorrt,ROS

Anaconda&#xff1a;https://repo.anaconda.com/archive/ Cuda&#xff1a;https://forums.developer.nvidia.com/t/pytorch-for-jetson/72048 1&#xff1a;安装Anaconda3 下载&#xff1a;Anaconda3-2021.11-Linux-aarch64.sh chmod x Anaconda3-2021.11-Linux-aarch64.s…

瑞_23种设计模式_工厂模式

文章目录 1 什么是工厂模式案例案例代码 2 简单工厂模式&#xff08;Simple Factory&#xff09;2.1 简单工厂模式的结构2.2 案例改进——简单工厂模式2.3 案例改进代码实现2.4 简单工厂模式优缺点2.5 拓展——静态工厂 3 工厂方法模式&#xff08;Factory Method&#xff09;★…

OJ_整数奇偶排序

题干 c实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<algorithm> using namespace std;//compare函数不交换返回true bool compare(int a, int b) {//1.a奇数&#xff0c;b偶数&#xff0c;不交换//2.a奇数&#xff0c;b奇数&#xff0c;a比b…

openGauss学习笔记-213 openGauss 性能调优-总体调优思路

文章目录 openGauss学习笔记-213 openGauss 性能调优-总体调优思路213.1 调优思路概述213.2 调优流程 openGauss学习笔记-213 openGauss 性能调优-总体调优思路 213.1 调优思路概述 openGauss的总体性能调优思路为性能瓶颈点分析、关键参数调整以及SQL调优。在调优过程中&…

【Redis】整理

对于现代大型系统而言&#xff0c;缓存是一个绕不开的技术话题&#xff0c;一提到缓存我们很容易想到Redis。 Redis整理&#xff0c;供回顾参考

TiDB架构设计和实践:高性能分布式数据库解决方案

摘要&#xff1a;TiDB是一个开源的分布式NewSQL数据库&#xff0c;具备强大的水平扩展能力和高性能查询能力。本文将介绍TiDB的架构设计和实践经验&#xff0c;帮助读者了解如何利用TiDB构建可靠、高性能的分布式数据库系统。 正文&#xff1a; ### 1. 引言 随着互联网规模的…

Struts2远程代码执行漏洞复现

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、漏洞介绍 Struts2漏洞是一个经典的漏洞系列&#xf…

探索智能巡检机器人深度学习的奥秘

机器人深度学习&#xff08;Robot Deep Learning&#xff09;是指利用深度学习技术&#xff0c;使机器人能够从大量数据中学习和提取特征&#xff0c;进而实现自主感知、决策和行动的能力。通过深度学习算法&#xff0c;机器人可以从传感器获取的数据中自动学习模式和规律&…

【SpringBoot】ApplicationContextAware 与 @Autowired 注解效果是一样,但是时机不一样

一、区别 ApplicationContextAware 是一个接口&#xff0c;它提供一个方法 setApplicationContext &#xff0c;当 spring 注册完成之后&#xff0c;会把 ApplicationContext 对象以参数的方式传递到方法里&#xff0c;在方法里我们可以实现自己的逻辑&#xff0c;去获取自己的…

深入了解关联查询和子查询

推荐阅读 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;一&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;二&#xff09; 文章目录 推荐阅读关联查询子查询 关联查询 关联查询 从多张表中查询对应记录的信息&#xff0c;关联查…

C++参悟:扩展资源

有用的资源 一、概述二、模式、手法、提示和技巧1. cpppatterns2. C Core Guidelines3. MSDN 三、第三方库 一、概述 在 cppreference 中我发现了很多比较有趣的扩展资源。我是从其官网下载的离线 chm 版本以便查看 https://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5 在我下…

一款轻量级、高性能、功能强大的内网穿透代理服务器

简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff08;访问内网网站、本地支付接口调试、ssh访问、远程桌面&#xff0c;内网dns解析等等……&#xff09;&#xff0c;此外还支持内网htt…

Python学习(15)|切片slice操作

38-切片 slice 操作类似字符串的切片操作&#xff0c;对于列表的切片操作和字符串类似。 切片操作&#xff1a; 切片是Python序列及其重要的操作&#xff0c;适用于列表、元组、字符串等。 切片slice操作可以让我们快速提取子列表或者修改。标准格式为&#xff1a; [起始偏移…

QT6调用音频输入输出(超详细)

目录 一、QT6音频调用与QT5的区别 1.QAudioSource代替QAudioInput类 2.QAudioSink代替QAudioOutput类 二、音频操作中Push和Pull的区别 三、依托于Websocket实现实时对讲机 1.AudioIputDevices类 2.AudioOutputDevices类 3.实现的AudioHandler类完整内容 本人实际是要完…

深度神经网络如何启用卤化物后端以提高效率

介绍 本教程指导如何使用 Halide 语言后端在 OpenCV 深度学习模块中运行模型。Halide 是一个开源项目&#xff0c;它让我们以可读性强的格式编写图像处理算法&#xff0c;根据特定设备安排计算并以相当高的效率对其进行评估。 卤化物项目的官方网站&#xff1a;Halide。 最新…

Maven工程的配置及使用

一、Maven章节 Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具 1.1、maven的作用 1&#xff09;依赖管理&#xff1a; 方便快捷的管理项目依赖的资源包&#xff08;jar包&#xff09;避免版本冲突 2&#xff09;统一项目结构&…

WebSocket学习笔记以及用户与客服聊天案例简单实现(springboot+vue)

一&#xff1a;介绍&#xff1a; 二&#xff1a;http协议与websocket对比&#xff1a; 三&#xff1a;websocket协议&#xff1a; 四&#xff1a;实现&#xff1a; 4.1客户端&#xff1a; 4.2服务端&#xff1a; 五&#xff1a;案例&#xff1a; 环境&#xff1a;做一个书店…

从0到1学Binder-环境准备

前言 终于要开始啃 binder 了&#xff0c;其实还没准备好&#xff0c;但是先走出去吧&#xff0c;目标是 2024 年一个整年能把 binder 学完。 我的微信公众号“ZZH的Android”&#xff0c;还有更多 Android 系统源码解析的干货文章等着你。 1 环境配置 Ubuntu 22.04 Cuttl…

计算机网络——03网络核心

网络核心 网络核心 网络核心&#xff1a;路由器的网络状态基本问题&#xff1a;数据怎样通过网络进行传输 电路交换&#xff1a;为每个呼叫预留一条专有电路分组交换 将要传送的数据分成一个个单位&#xff1a;分组将分组从一个路由器传到相邻路由器&#xff08;hop&#xff…