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("."));
    
            //上传文件到 OSS
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            ossClient.putObject(bucketName, fileName, inputStream);
    
            //文件访问路径
            String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
            // 关闭ossClient
            ossClient.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 {
    
        @Bean
        public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){
            AliOSSUtils aliOSSUtils = new AliOSSUtils();
            aliOSSUtils.setAliOSSProperties(aliOSSProperties);
            return aliOSSUtils;
        }
    }
    

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

3、总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 Flink(五)Flink Standalone 集群启动源码剖析

前言 Flink 集群的逻辑概念&#xff1a; JobManager(StandaloneSessionClusterEntrypoint) TaskManager(TaskManagerRunner) Flink 集群的物理概念&#xff1a; ResourceManager(管理集群所有资源&#xff0c;管理集群所有从节点) TaskExecutor(管理从节点资源&#xff0c;接…

order by 与 分页 的冲突

order by 与 分页 的冲突 问题背景 Oracle拼接SQL&#xff0c;JAVA使用SQLQueryExecutor执行拼接的SQL&#xff0c;SQL如下&#xff1a; SELECT col_key, col_other_info FROM tb_tableName WHERE col_where_info 一些筛选条件 order by col_updatetime desc 该表中的数…

python 计数器

这个Python脚本定义了一个名为new_counter()的函数&#xff0c;它读取系统时间并将其与存储在文件中的时间进行比较。然后根据比较结果更新存储在另一个文件中的计数器值。如果系统时间与存储的时间匹配&#xff0c;则计数器值增加1。如果系统时间与存储的时间不匹配&#xff0…

JS逆向实战案例1——某房地产url动态生成

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、 反爬分析 url&#xff1a;aHR0cHM6Ly9uZXdob3VzZS4wNTU3ZmRjLmNvbQ 该站点项目url通过点击JS生成&#xff0c;project_id与生成后…

SQL SERVER 19安装 SQL Prompt 10.02版本

SQL Prompt最新版官网下载地址&#xff1a;https://download.red-gate.com/SQLPromptDownload.exe 下载完成后&#xff0c;断开网络&#xff0c;全部点下一步。 注册机会报毒&#xff0c;安装前请先关闭杀毒软件&#xff01; 下载好附件之后解压&#xff0c;打开SQLPrompt_7…

深入理解 Flink(六)Flink Job 提交和 Flink Graph 详解

Flink Program 编程套路回顾 1、获取执行环境对象 StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(); 2、通过执行环境对象&#xff0c;注册数据源 Source&#xff0c;得到数据抽象 DataStream ds env.socketTextStream(...) 3、调用数…

【RabbitMQ】2 RabbitMQ介绍与架构

目录 简介架构Connection 和Channel关系工作流程生产者发送消息的流程消费者接收消息的过程 RabbitMQ数据存储存储机制 安装和配置RabbitMQRabbitMQ常用操作命令 简介 RabbitMQ&#xff0c;俗称“兔子MQ”&#xff08;可见其轻巧&#xff0c;敏捷&#xff09;&#xff0c;是目…

AI系统ChatGPT网站系统源码AI绘画详细搭建部署教程,支持GPT语音对话+DALL-E3文生图+GPT-4多模态模型识图理解

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

2019年认证杯SPSSPRO杯数学建模C题(第一阶段)保险业的数字化变革全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 基于 CART 决策树和 SVR 的客户续保概率预测 C题 保险业的数字化变革 原题再现&#xff1a; 车险&#xff0c;即机动车辆保险。保险自身是一种分散风险、消化损失的经济补偿制度&#xff0c;车险即为分散机动车辆在行驶过程中可能发作的未知风…

PPT插件-大珩助手-修改素材名称及搜索功能演示

修改素材名称及搜索功能演示 大珩助手的素材库&#xff0c;支持修改素材的名称&#xff0c;支持动态查找素材&#xff0c;删除素材 移动素材到其他分类 软件介绍 PPT大珩助手是一款全新设计的Office PPT插件&#xff0c;它是一款功能强大且实用的PPT辅助工具&#xff0c;支持…

服务网格 Service Mesh

什么是服务网格&#xff1f; 服务网格是一个软件层&#xff0c;用于处理应用程序中服务之间的所有通信。该层由容器化微服务组成。随着应用程序的扩展和微服务数量的增加&#xff0c;监控服务的性能变得越来越困难。为了管理服务之间的连接&#xff0c;服务网格提供了监控、记…

使用阿里云镜像创建一个Spring Boot项目

由于现在的idea在创建项目时已经不支持Java8版本了&#xff0c;如果我们还想用8版本&#xff0c;可以使用阿里云镜像创建。所以得改变原有的地址为&#xff1a;https://start.aliyun.com springboot版本选择2开头的任意版本的。 1.配置6个依赖 2.改变下载依赖地址 下载依赖默认…

语境化语言表示模型-ELMO、BERT、GPT、XLnet

一.语境化语言表示模型介绍 语境化语言表示模型&#xff08;Contextualized Language Representation Models&#xff09;是一类在自然语言处理领域中取得显著成功的模型&#xff0c;其主要特点是能够根据上下文动态地学习词汇和短语的表示。这些模型利用了上下文信息&#xf…

Linux ----冯诺依曼体系结构与操作系统

目录 前言 一、冯诺依曼体系结构 二、为什么选择冯诺依曼体系结构&#xff1f; 三、使用冯诺依曼结构解释问题 问题1&#xff1a; 问题2: 四、操作系统 1.操作系统是什么 2.为什么需要操作系统 3.操作系统怎样管理的 4.如何给用户提供良好环境 五、我们是怎样调用系…

【冥想X理工科思维】场景6:我被调岗了…

冥想音频合集&#xff1a;职场解压冥想音频 压力场景&#xff1a; 领导把我调换到并不喜欢也不擅长的岗位&#xff0c;如何借助冥想面对职业发展或公司变动时的不确定性和焦虑&#xff1f; 点击看大图&#xff1a; 详细说明&#xff1a; 在面对工作中的挑战时&#xff0c;制定一…

shp文件与数据库(创建shp文件)

前言 前面把shp文件中的内容读取到数据库&#xff0c;接下来就把数据库中的表变成shp文件。 正文 简单的创建一个shp文件 暂时不读取数据库的表&#xff0c;先随机创建一个shp文件。既然是随机的&#xff0c;这就需要使用到faker这个第三方库&#xff0c;代码如下。 impor…

mysql的gtid主从复制,从库误操作更新操作,

一&#xff1a;查看mysql的从库&#xff0c;发现sql进程状态 “no”.提示执行传输过来的binlog日志&#xff0c;执行失败&#xff0c; 二&#xff1a;查看主库对应的二进制日志的gtid地方。插入一些数据。 # mysqlbinlog --base64-outputdecode-rows -v mysql-bin.000001 |gre…

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

HackTheBox-Keeper

OpenVPN连接 连接上HackTheBox&#xff01; 同时找到这个靶机&#xff0c;进行join&#xff01;分配的靶机的地址位10.10.11.227&#xff01; 信息收集 nmap -sT --min-rate 10000 -p- 10.10.11.227 开放端口为22和80端口 服务版本和操作系统信息探测&#xff1a; nmap -s…

6.3、SDN在云计算中的应用

目录 一、SDN概念 1.1、传统网络机制 1.2、SDN网络机制 1.3、二者区别 1.4、SDN架构 二、云数据中心 2.1、公有云环境特点 2.2、两大挑战 2.3、云数据中心引入SDN技术解决两大挑战 三、SDN云计算解决方案 3.1、SDN云计算解决方案之控制平面openflow协议 3.1.…