SpringBoot——原理(自动配置_案例(自定义阿里云文件上starter))

news2024/9/28 17:26:54

starter定义

starter就是springboot中的起步依赖,虽然springboot已经提供了很多的起步依赖,但是在实际项目开发中可能会用到和第三方的技术,不是所有第三方在springboot中都有收录。

比如之前文章中有用到过的阿里云OSS,阿里云并没有提供起步依赖,导致每次使用时都要自己写一些类。

springboot官方提供的起步以来是spring-boot在前,其他提供的通常都是技术名在前。

下面mybatis的起步依赖中没有java代码,只是整合了mybatis开发需要的依赖的坐标 其中包含了一个依赖mybatis-spring-boot-autoconfigure,这个自动配置类里面声明了一堆Bean对象。

 里面可以看见一些常用的类比如SqlSessionFactory 

那么这些配置类配置好之后是如何被SpringBoot项目加载到IOC容器并完成自动配置的呢?

前面有说到过,SpringBoot在启动时会加载依赖中的两份文件,如果是老版本的就加载spring.factories,如果是新版本的就加载autoconfigure.import这个文件。

因此该自动配置类配置好之后,就可以在spring.factories或者是autoconfigure.import文件中配置这个自动配置类。

最终会儿被加载到spring的IOC容器当中.

因此自定义一个起步依赖starter的时候按照规范需要定义两个模块,一个是starter模块,其唯一的作用就是进行依赖管理。

另一个autoconifure的包就是完成自动配置的操作。 

最终在项目中只会导入starter模块,因为starter已经导入了autoconfigure模块了。        

上面就是简单介绍了自定义starter的场景以及自定义starter涉及的各个模块和各个模块涉及的功能.

自定义starter案例

需求说明

在不封装的时候,每次使用都要自己手动写一些OSS的工具类并添加到IOC容器当中去。

根据阿里云官方提供的示例SDK文件改造成如下一个工具类,并在yml配置文件当中配置需要的参数,然后还要一个实体类加载配置文件中的配置项。

最后才可以在工具类中获取到需要的参数,然后交给springIOC容器管理,然后在项目用到时就直接注入。

这个过程十分的繁琐

 

具体封装看这里一下两篇文章

云服务——阿里云OSS的入门使用_北岭山脚鼠鼠的博客-CSDN博客SpringBoot——SB整合mybatis案例(残缺版本)第三集_北岭山脚鼠鼠的博客-CSDN博客

上面的这个过程是十分繁琐且重复的一个过程,因此可以将其封装成一个依赖项,可以通过坐标引入后直接使用。

步骤分析

具体实现 

创建好两个需要的模块

选择新建新模块

首先新建一个starter模块

 规整starter模块的pom.xml文件如下

先改版本为2.7.5,再删除多余的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-oss-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

然后starter模块的项目文件删除的只剩下一个pom.xml和一个iml文件。

然后再新建一个autoconfigure的模块,按照上面的流程再走一次

然后修改 autoconfigure模块的pom.xml如下,将项目文件删成如下的结构,只比上面多一个src

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

</project>

将来autoconfigure是作为其他项目文件的依赖的,所以application这个启动类不需要,配置文件也不需要,测试单元也不需要。删除如下图所示的三个文件 

模块创建工作结束 (上面就准备好了一个依赖所需要的两个基本模块了)

然后需要在starter模块引入autoconfigure模块,这是前面提到过的规范。

直接导入autoconfigure的坐标。

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

在autoconfigure中完成自动配置操作

 根据目标需求,需要在autoconfigure准备一个AliyunOSSUtils工具类。

1.引入依赖

要在项目中使用阿里云OSS需要引入阿里云OSS的依赖,引入如下依赖在autoconfigure中

        <!--阿里云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>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>

2.准备工具类和实体类 

在之前的项目开发中使用阿里云OSS时需要用到的类有一个工具类和一个实体类

实体类里面封装的是阿里云的key和id还有资源桶的名字

package com.example.utils;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}

还有一个工具类

package com.example.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.UUID;

/**
 * 阿里云 OSS 工具类
 */

@Component
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 ;

/*    @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;*/


    @Autowired
    private AliOSSProperties aliOSSProperties;

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {
        String endpoint=aliOSSProperties.getEndpoint();
        String bucketName=aliOSSProperties.getBucketName();
        String accessKeyId=aliOSSProperties.getAccessKeyId();
        String accessKeySecret=aliOSSProperties.getAccessKeySecret();

        // 获取上传的文件的输入流

        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的路径返回
    }

}

将上面两个文件放到autoconfigure项目中时会有一个报错,需要引入两个新的依赖

一个是web开发的以来,一个是@Data注解的依赖,又或者可以不引入lombok的以来,然后手动提供get和set方法。直接把@Data的注解去掉即可,然后alt+insert即可

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

然后两个类都没有报错了,但是现在两个类上的component注解已经没有用了,因为将来这个依赖引入项目时包扫描也不会扫这个依赖模块的包,所以两个类上的@component注解可以删除了。

注意:这里删除会导致aliOSSProperties实体类出现红色报错,但是这里可以先不用管,下面会解决。

然后还有工具类里面的@Autowired也可以删除了,因为已经不是IOC容器里面的Bean了,不能进行autowired注入了。

但是根据需求提到的直接注入工具类直接使用,所以还是要将其交给spring容器进行管理。

因此现在需要准备一个自动配置类来声明阿里云OSS的这个工具类的Bean,然后将配置类交给spring容器管理。

3.新建自动配置类

这个配置类可以获取到AliOSSUtils这个工具类的,然后直接使用upload方法进行文件上传操作,但是在那之前upload方法里面是还需要一个aliOSSProperties成员变量的,所以在工具类当中还要准备它的get和set方法.

然后在获取到AliOSSUtils时还需要为里面的aliOSSProperties赋值。

然后aliOSSProperties当中需要的属性值都是从配置文件当中获取得到的,然后封装成一个aliOSSProperties实体类。

@ConfigurationProperties(prefix = "aliyun.oss")

这里需要解决上面这块的报错问题,可以直接在自动配置类上加上如下的注解,将AliOSSProperties变成一个IOC容器中Bean对象就不会报错了。

@EnableConfigurationProperties(AliOSSProperties.class)

再然后在配置类,声明一个第三方Bean时需要注入某一个对象可以直接在方法形参中指定,最终会自动装配进来。


@Configuration
@EnableConfigurationProperties(AliOSSProperties.class)
public class AliOSSAutoConfiguration {
    @Bean
    public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){
        AliOSSUtils aliOSSUtils= new AliOSSUtils();
        aliOSSUtils.setAliOSSProperties(aliOSSProperties);
        return aliOSSUtils;
    }
}

到这里,自动配置类已经配置好了,另外两个类别忘记删除@Component和@Autowried注解并且加上aliOSSProperties的get还有set方法就可以了。

4.最后一步

要想自动配置类被加载到项目中就需要在一个固定的配置文件中来配置。

就是META-INF/spring/xxx.imports中,所以现在autoconfigure模块的resources目录下新建一个对应的文件夹和需要的一个名字很长的文件。

注意名字不能打错。

在这个文件中的都是自动配置类的全类名,所以要把上面写好的一个自动配置类放到里面去。 

com.aliyun.oss.AliOSSAutoConfiguration

到此,这个starter已经定义完了,在starter中进行依赖管理,在configure中进行自动配置。

在测试工程中对封装好的starter进行测试

在提供的资源中有一个测试工程。

在这个测试工程的Controller层中有一个uploadController如下,需要将接收到文件上传到阿里云OSS。

然后这里可以直接引入上面的起步依赖,然后就可以直接上传文件到OSS了。

在测试工程的pom文件当中,引入如下依赖。

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-oss-spring-boot-starter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

 然后就需要在配置文件当中需要一些阿里云账号的参数,需要的配置信息有如下的四项,都需要在测试工程的配置文件上准备好。

这里根据个人的实际账号资料进行配置。 

 

最后在controller当中实现如下,将已经上传的文件交给阿里云OSS进行保存

@RestController
public class UploadController {
    @Autowired
    private AliOSSUtils aliOSSUtils;


    @PostMapping("/upload")
    public String upload(MultipartFile image) throws Exception {
        //上传文件到阿里云 OSS
        String url=aliOSSUtils.upload(image);
        return url;
    }
}

项目运行测试 (使用postman测试)

上面那里将依赖导入别的项目时可能会有出现Cannot reconnect的傻狗报错,这时候只需要重启IDEA即可。

成功上传文件到阿里云并且获得了文件url。 

完成了这个依赖封装,我就可以自己搞一个网页,然后自己上传自己的东西,然后自己下载自己的东西了。 真不错。

小结

 SpringBoot原理章节完结撒花!

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

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

相关文章

chatgpt赋能python:**Python中的SEO:正确与错误**

Python中的SEO&#xff1a;正确与错误 对于任何一个网站&#xff0c;无论其大小和规模&#xff0c;搜索引擎优化(SEO)都是必不可少的。作为一种流行的编程语言&#xff0c;Python也可以用来优化和改进SEO操作。在本文中&#xff0c;我们将探讨Python中对于SEO的正确和错误使用…

[笔记]C++并发编程实战 《三》线程间共享数据

文章目录 前言第3章 线程间共享数据3.1 共享数据带来的问题3.1.1 条件竞争3.1.2 避免恶性条件竞争 3.2 使用互斥量保护共享数据3.2.1 C中使用互斥量3.2.2 用代码来保护共享数据3.2.3 定位接口间的条件竞争选项1&#xff1a; 传入一个引用选项2&#xff1a;无异常抛出的拷贝构造…

vuex最详细笔记总结,这些东西你真的了解吗?

1.vuex是啥&#xff1f; 简单来说就是管理数据的,相当于一个仓库,里面存放着各种需要共享的数据,所有组件都可以拿到里面的数据 2.什么时候使用vuex 1.多个组件依赖于同一状态 2.来自不同组件的行为需要变更同一状态 总之&#xff0c;就是vuex作为一个仓库&#xff0c;任何组件…

和ChatGPT关于Swing music的一场对话(下篇)

昨天无意中刷到的系统推送的文章 点进去一看&#xff0c;原来介绍的就是老苏为了抛砖引玉编的 Swing music 的镜像&#xff0c;动作真是快啊。 坦白的说&#xff0c;文章比老苏写的好&#xff0c;所以让我纠结了好一阵子&#xff0c;本文我是发呢还是不发呢&#xff1f;不过似…

jQuery实现响应式瀑布流效果(jQuery+flex)

瀑布流原理&#xff1a;是一种常见的网页布局方式&#xff0c;它的特点是将内容以多列的形式呈现&#xff0c;每一列的内容高度不固定&#xff0c;根据内容的大小自适应调整&#xff0c;从而形成了像瀑布一样的流动效果。 瀑布流的实现原理涉及到数据加载、布局设计、图片加载和…

ML算法——KNN随笔【全国科技工作者日创作】【机器学习】

9、K-Nearest Neighbors (KNN) 9.1、理论部分 K最邻近算法 把一个物体表示成向量【特征工程】,且 KNN 需要考虑 【特征缩放】。标记每个物体的标签计算两个物体之间的距离/相似度选择合适的 K 未知点的判断基于已知点的距离&#xff0c;选出最近的K个点&#xff0c;投票选出…

pyjail初了解

前言 最近在各种比赛Misc方向都能多多小小看到Python jail题&#xff0c;通过eval或者exec等函数执行Python的代码获取shell&#xff0c;实现Python逃逸&#xff0c;但是我不是太会&#xff0c;因此找点题目做一下&#xff0c;总结一下。 常用Python的魔术方法 _init_:用于P…

chatgpt赋能python:Python中小数点保留的几种方法

Python中小数点保留的几种方法 作为一名Python工程师&#xff0c;我们经常需要对数字进行处理。在处理时&#xff0c;我们需要将数字进行格式化&#xff0c;例如保留小数点后几位或添加千位分隔符等。其中&#xff0c;保留小数点后几位是比较常见的需求。本文将介绍Python中小…

chatgpt赋能Python-python中怎么安装aip

概述 在现代的SEO中&#xff0c;使用机器学习和自然语言处理的API来分析关键字和网页内容已经成为一个普遍的实践。Google API是其中最受欢迎的一个&#xff0c;因为它可以提供多种功能&#xff0c;包括分析关键字、分析文本和图像识别等。 Python作为一种优秀的脚本语言&…

Linux Apache 配置与应用 【虚拟主机 连接保持 日志分割 分析系统 优化网页】

--------构建虚拟 Web 主机-------- 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务器&#xff0c;因此被称为“虚拟”Web 主机。通过虚拟 Web 主机服务可以充分利用服务器的硬件资源&#xff0c;从而大大降低网站构建…

《深入理解计算机系统(CSAPP)》第8章 异常控制流 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习CSAPP时的个人笔记&#xff0c;分享出来与大家学习交流&#xff0c;目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记&#xff0c;在复习回看时发现部分内容存在一些小问题&#xff0c;因时间紧张来不及再次整理…

chatgpt赋能python:Python合并函数:一个简单但有用的工具

Python合并函数&#xff1a;一个简单但有用的工具 Python是一种优雅而强大的编程语言&#xff0c;拥有许多内置的函数和库&#xff0c;可以让编程变得更加简单和高效。其中&#xff0c;合并函数是一个非常有用的工具&#xff0c;它可以让我们快速而灵活地合并和处理数据。 什…

5月30日第壹简报,星期二,农历四月十二

5月30日第壹简报&#xff0c;星期二&#xff0c;农历四月十二坚持阅读&#xff0c;静待花开1. 比亚迪&#xff1a;自主研发了常压油箱的燃油蒸汽排放控制技术&#xff0c;能符合蒸发排放法规标准&#xff0c; 愿与所有同行共享核心技术专利。2. 中国计划2030年前实现首次登月&a…

chatgpt赋能python:Python中升序和降序排序:什么是升序和降序以及如何使用Python进行排序

Python中升序和降序排序&#xff1a;什么是升序和降序以及如何使用Python进行排序 介绍 Python是一种强大的编程语言&#xff0c;可以用来处理各种类型的数据。其中包括对数据进行排序&#xff0c;Python具有方便且易于使用的排序功能。在Python中&#xff0c;可以使用升序和…

chatgpt赋能python:Python中可迭代对象的介绍

Python中可迭代对象的介绍 Python是一种高级编程语言&#xff0c;它具有简单易学、可读性强、功能强大等特点&#xff0c;成为了数据科学、机器学习、Web开发等领域的热门选择。Python中有很多重要的概念和功能&#xff0c;其中之一就是支持可迭代对象的概念。 在Python中&am…

chatgpt赋能python:Python中如何生成表格

Python中如何生成表格 在数据分析和处理中&#xff0c;表格是一种常见的数据格式&#xff0c;并且在不同的场景下都有着不同的用途。Python作为一种高效的编程语言&#xff0c;可以帮助我们轻松地生成和操作表格数据。在本文中&#xff0c;我们将介绍Python中生成表格的方法&a…

IDEA控制台tomcat 乱码

问题 IDEA控制台tomcat 乱码 详细问题 项目部署至tomcat上&#xff0c;启动tomcat&#xff0c;IDEA控制台终端Server日志&#xff0c;Tomcat Localhost日志&#xff0c;Tomcat Catalina日志乱码 Server日志 D:\tomcat9\bin\catalina.bat run [2023-05-29 11:20:24,521] Art…

【Linux】在Ubuntu中卸载、下载mysql以及如何检查mysql是否卸载成功

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

5.30黄金空头能否延续?今日多空如何布局?

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周一(5月29日)进入欧市盘中&#xff0c;对美国周末达成债务上限协议的乐观情绪推动风险情绪回升&#xff0c;与此同时&#xff0c;上周公布的美国PCE数据让美联储难…

ChatGPT Sorry, you have been blocked(抱歉,您已被屏蔽)的解决方法

最近在使用 ChatGPT 时大家遇到的最多的问题就是 Sorry, you have been blocked&#xff08;抱歉&#xff0c;您已被屏蔽&#xff09;了&#xff0c;之前的 Access denied 似乎都不常见了&#xff0c;今天老王就分享下这个问题的原因和解决方法。 一、ChatGPT 被屏蔽 blocked …