SpringBoot原理(@Conditional)—三种自动配置方法、步骤详解

简介:我们一直在说基于SpringBoot开发简单、快捷,但是总是不太清楚为什么会有这样的便利,对于开发人员来说我们不仅要知其然,还要知其所以然,这篇文章就是说明SpringBoot的底层原理,让读者对SpringBoot底层的运行机制有深一层的了解。

目录

1、起步依赖

2、自动配置

2.1 自动配置原理

2.2 @Conditional注解

2.3 案例(自定义starter)

3、总结


1、起步依赖

  • SpringBoot 通过提供众多起步依赖降低项目依赖的复杂度。起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。很多起步依赖的命名都暗示了它们提供的某种或某类功能。

2、自动配置

  • SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们去手动声明,从而简化了开发,省去了繁琐的配置操作。

2.1 自动配置原理

  • 方案一:@ComponentScan 组件扫描
图 2.1-1 添加第三方地址
上图是在当前项目的pom.xml配置文件中添加第三方项目的地址,从而可以在当前项目引用第三方项目资源。
图 2.1-2 @ComponentScan()注解 

上图中的 @ComponentScan()注解定义在当前项目启动类中,当前项目启动时会自动扫描参数中包名的所有bean对象并将其存储到IOC容器中。

优势:能全面的扫描的包内的所有bean对象。

缺点:性能慢,开发中不是所有的bean都需要(主流开发不使用)。

  • 方案二:@import导入。使用@import导入的类会被加载到IOC容器中,导入的形式主要有以下几种:
    • 导入 普通类
    • 导入 配置类
    • 导入 ImportSelector 接口实现类
    • @EnableXxxx注解,封装@import注解
图 2.1-3  添加第三方项目地址
图片中展示的是在本项目的pom.xml文件中添加第三方项目的地址依赖,这样就可以在本项目中使用第三方的资源。(备注:下面几种,第三方bean对象导入IOC容器中,都是在第三方项目的地址已经在pom.xml文件中的基础上
图 2.1-4 import 导入普通类、配置类
上图中是通过@Import() 注解(注解中的参数为被调用第三方资源的类名称),调用第三方项目的资源且将被调用的资源对象存储到IOC容器中。
图 2.1-5 导入 ImportSelector 接口实现类

上图是在被调用第三方项目中创建一个 ImportSelector 接口的实现类  MyImportSelector ,实现类返回值为允许被调用bean对象资源的全类名。

图 2.1-6 导入 ImportSelector 接口实现类

上图是在当前项目启动类中通过 @Import 注解,将第三方项目的接口实现类(图 2.1-5)MyImportSelector导入。

图 2.1-7 使用@EnableXxxx注解
上图是在图2.1-6的基础上,在第三方资源项目中创建 EnableHeaderConfig注解并且使用 @Import()注解引用第三方资源项目的接口实现类  MyImportSelector,这样开发者直接在当前开发项目中直接使用 EnableHeaderConfig注解就可以了。  这也是当前开发工作中的主流方式。

2.2 @Conditional注解

图 2.2-1 使用@Conditional注解
上图是 @Conditional的作用,他是一个父级注解,开发中最主要的就是三个字注解,需要掌握这三个子注解的使用方法。
图 2.2-2 使用@Conditional 相关子注解

上图中在第三方资源项目中的 HeaderConfig类中,使用了三个注解;

  1. @ConditionalOnMissingBean //不存在该类型的bean,才会将该bean加入到IOC容器中 -- 指定类型(value属性) 或 名称(name属性)
  2. @ConditionalOnClass(name = "io.jsonwebtoken.Jwts") //环境中存在指定的这个类,才会将该bean加入IOC容器中
  3. @ConditionalOnProperty() //配置文件中存在指定的属性与值,才会将该bean加入到IOC容器中

开发者可以根据需要,自主在第三方资源项目中选择使用这三个注解中适用的,方便将注解对应的bean对象放进当前引用的第三方资源

2.3 案例(自定义starter)

在实际的开发过程中,经常会定义一些公共组件,提供给各个项目团队使用。而在SpringBoot的项目中,一般会把这些公共组件封装为SpringBoot的starter。

下面是在IDEA项目中创建一个自定义starter依赖,关于操作阿里云OSS的操作工具类。

图 2.3-1 自定义starter
图片中是创建一个阿里云OSS操作工具类的项目依赖步骤,分为依赖管理功能、自动配置功能。
图 2.3-2 创建starter
图 2.3-3 创建autoconfigure模块
上图中是在当前项目中创建autoconfigure模块,并且只保留pom.xml、iml、src文件,其他的删除掉。

之后是在创建的autoconfigure模块中的pom.xml文件中添加阿里云的相关依赖(代码如下)

        <!--web起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--添加阿里云的依赖--><!--阿里云OSS--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency>

只有在autoconfigure模块中的pom.xml文件中添加依赖后,才能编写代码。

  1. 接下来是去创建 AliOSSProperties 类,这是一个属性类,用于记录阿里云的秘钥等数据(代码如下)
    package com.aliyun.oss;import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;@Data
    @ConfigurationProperties(prefix = "aliyun.oss")
    public class AliOSSProperties {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;
    }
    
  2. 之后是创建阿里云OSS工具类  AliOSSUtils,这个类的功能是将文件上传至阿里云中(代码如下)
    package com.aliyun.oss;import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
    import java.io.InputStream;
    import java.util.UUID;/*** 阿里云 OSS 工具类*/
    public class AliOSSUtils {//    @Value("${aliyun.oss.endpoint}")
    //    private String endpoint ;
    //    @Value("${aliyun.oss.accessKeyId}")
    //    private String accessKeyId ;
    //    @Value("${aliyun.oss.accessKeySecret}")
    //    private String accessKeySecret ;
    //    @Value("${aliyun.oss.bucketName}")
    //    private String bucketName ;private AliOSSProperties aliOSSProperties;public AliOSSProperties getAliOSSProperties() {return aliOSSProperties;}public void setAliOSSProperties(AliOSSProperties aliOSSProperties) {this.aliOSSProperties = aliOSSProperties;}/*** 实现上传图片到OSS*/public String upload(MultipartFile file) throws IOException {//获取阿里云OSS参数String endpoint = aliOSSProperties.getEndpoint();String accessKeyId = aliOSSProperties.getAccessKeyId();String accessKeySecret = aliOSSProperties.getAccessKeySecret();String bucketName = aliOSSProperties.getBucketName();// 获取上传的文件的输入流InputStream inputStream = file.getInputStream();// 避免文件覆盖String originalFilename = file.getOriginalFilename();String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));//上传文件到 OSSOSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);ossClient.putObject(bucketName, fileName, inputStream);//文件访问路径String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;// 关闭ossClientossClient.shutdown();return url;// 把上传到oss的路径返回}}
    
  3. 最后是创建一个 AliOSSConfiguration 配置类,用于将阿里云的 AliOSSUtils 对象存放如IOC容器中。
    package com.aliyun.oss;import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;@Configuration
    @EnableConfigurationProperties(AliOSSProperties.class)
    public class AliOSSConfiguration {@Beanpublic AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){AliOSSUtils aliOSSUtils = new AliOSSUtils();aliOSSUtils.setAliOSSProperties(aliOSSProperties);return aliOSSUtils;}
    }
    

接下来定义配置文件,用于IDEA找到AliOSSConfiguration 配置类对象(如下图)

3、总结

以上就是关于SpringBoot原理(@Conditional) — 三种自动配置方法、步骤详解。小编初次接触的时候还是觉得比较绕的,后面自己多思考动手还思维导图,总算是理解并且记住了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Emoji表情大全

等等... 推荐一下几个网站&#xff0c;去复制就可以啦&#xff01; Emoji 表情大全All Emoji Symbols Are Collected Here, And Now Emoji Can Display On IOS, Android, OSX, And Windows Systems. Just The Symbol ✂ And &#x1f4cb; To App, SMS, Facebook, Twitter An…

一卡通水控电控开发踩过的坑

最近在做一个项目&#xff0c;是对接一卡通设备的。我一开始只拿到设备和3个文档开局。不知道从哪下手。一步一步踩坑过来。踩了很多没有必要的坑&#xff0c;写出来给有用的人吧。 读卡器怎么用&#xff1f; 有个读卡器&#xff0c;一开始什么软件也不提供。我都不知道是干嘛…

基于JavaWeb+BS架构+SpringBoot+Vue+Hadoop的物品租赁系统的设计与实现

基于JavaWebBS架构SpringBootVueHadoop的物品租赁系统的设计与实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 目  录 I 1绪 论 1 1.1开发背景 1 1.2开发目的与意义 1 1.2.1开发目…

Rabbit R1是一款AI驱动的小工具,可以代替你使用应用程序

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

CES 2024丨引领变革,美格智能为智能终端带来生成式AI能力

作为电子行业的“风向标”&#xff0c;CES 2024&#xff08;国际消费电子展&#xff09;于1月9日至12日在美国拉斯维加斯举办。本届展会可谓是AI的盛宴&#xff0c;芯片、AI PC、智能家居、汽车科技、消费电子等领域与AI相关的前沿成果接连发布&#xff0c;引领人工智能领域的科…

MySQL 按日期流水号 条码 分布式流水号

有这样一个场景&#xff0c;有多台终端&#xff0c;要获取唯一的流水号&#xff0c;流水号格式是 日期0001形式&#xff0c;使用MySQL的存储过程全局锁实现这个需求。 以下是代码示例。 注&#xff1a;所有的终端连接到MySQL服务器获取流水号&#xff0c;如果获取到的是 “-1”…

.NET 反射的介绍和简单应用

什么是反射&#xff1f; 反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型&#xff0c;这些信息在设计时是未知的&#xff0c;这种能力类似于后期绑定。反射还支持的更高级的行为&#xff0c;能在运行时动态创建新类型&#xff0…

Ubuntu 20.04 Intel RealSense D435i 相机标定教程

下载编译code_utils mkdir -p ~/imu_catkin_ws/src cd ~/imu_catkin_ws/src catkin_init_workspace source ~/imu_catkin_ws/devel/setup.bash git clone https://github.com/gaowenliang/code_utils.git cd .. catkin_make报错&#xff1a;sumpixel_test.cpp:2:10: fatal err…

Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

在 Spring 中&#xff0c;Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时&#xff0c;该方法将在单独的线程中执行&#xff0c;而不会阻塞当前线程。这使得方法可以在后台执行&#xff0c;而不会影响主线程的执行。 在您提供的代码示例中&#xff0c;a1() 和…

纯html通过XMLHttpRequest访问java后端接口并将返回结果输出到控制台【建议收藏】

我们需要准备几个部分&#xff1a; 1、后端接口【servlettomcat】 2、前端页面代码 3、js发起请求部分 后端接口&#xff1a; WebServlet("/h1") public class HController extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpS…

记录一下Canal的错误,主要是top.javatool.canal.client.util下的StringConvertUtil引起的

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 由于数据库的一个localdatetime字段是空的&#xff0c; 然后修改数据库数据同步canal的时候报了这个错误&#xff1a; Caused by: java.lang.IllegalArgumentException: Can not set java.time.LocalD…

在 WinForms 应用中使用 FtpWebRequest 进行文件操作和数据显示

在 WinForms 应用中使用 FtpWebRequest 进行文件操作和数据显示 引言 在企业级应用或桌面程序中&#xff0c;经常需要从远程服务器获取数据&#xff0c;并在用户界面上展示这些数据。本文将通过一个实际案例&#xff0c;演示如何在 Windows Forms 应用程序中使用 FtpWebReques…