[Java]SpringBoot能力进阶

news2024/9/20 15:01:37

配置优先级

SpringBoot中支持三种格式的配置文件

  1. 优先级: application.properties文件 > application.yml文件 > application.yaml文件

SpringBoot除了通过配置文件配置属性, 还支持Java系统属性和命令行参数的方式 进行属性配置

1.在IDEA中配置java系统属性和命令行参数

2.在命令行中配置java系统属性和命令行参数

配置文件和java属性以及命令行参数的优先级

bean的管理

手动获取bean

默认情况下, Spring项目启动时, 会把bean对象都创建好放在IOC容器中, 如果需要主动获取这个bean, 可以通过下面的方法

@SpringBooTest
class SpringbootWebConfig2ApplicationTest {
     @Autowired
     private ApplicationContext applicationContext;  //注入IOC容器对象
    
     //获取bean对象
     //根据bean的名称获取
     //获取到的bean是Object类型, 所以要进行强转 
     DeptController bean1 = (DeptController) applicationContext.getBean("deptController");
     System.out.println(bean1);

     //根据bean的类型获取
     DeptController bean2 = applicationContext.getBean(DeptController.class);
     System.out.println(bean2);

     //根据bean的名称及类型获取
     DeptController bean3 = applicationContext.getBean("deptController",DeptController.class);
     System.out.println(bean3);
}

执行效果

  1. 默认情况下bean是单例模式, 所以拿到的是同一个bean对象

bean的作用域

Spring支持五种作用域, 后三种在web环境才生效

可以通过 @Scope("作用域值")注解 设置bean的作用域

  1. 默认springboot中的bean, 在容器启动时就会被创建,
  2. 可以使用 @Lazy注解 来延迟初始化(延迟到第一次使用时创建)
  3. prototype的bean, 每一次使用该bean的时候都会创建一个新的实例
  4. 实际开发中, 绝大部分的bean都是单例的, 不需要配置scope属性

第三方bean

如果要管理的bean对象来自于第三方, 是无法用 Component及其衍生注解 声明bean的, 而是需要SpringBoott提供的 @Bean注解 完成bean的声明

@SpringBootTest
class TliasWebManagementApplicationTests {

    // 第三方bean的管理
    @Test
    public void testThirdBean() throws Exception {
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(this.getCLass().getClassLoader().getResource('1.xml'));
        Element rootElement = document.getRootElement();
        String name = rootElement.element("name").getText();
        String age = rootElement.element("age").getText();

        System.out.printIn(name + ":" + age)
    }

}
  1. 第三方文件是只读的, 无法通过添加 @Compoment 注解的形式完成bean的声明
  2. 此时使用第三方对象是只能手动创建, 但是执行效率比较低, 因为无法复用该对象, 耗费资源

在启动类中注册第三方bean对象, 非常简单, 但是不推荐, 因为启动类要保持简洁

@SpringBootApplication
public class TliasWebManagementApplication {

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

    // 声明第三方bean
    // 将当前方法的返回值对象,交给IOC容器管理,称为IOC容器的bean 
    @Bean
    public SAXReader saxReader() {
      return new SAXReader();   
    }
}
@SpringBootTest
class TliasWebManagementApplicationTests {

    @Autowired
    private SAXReader saxReader;
    
    @Test
    public void testThirdBean() throws Exception {
        // 不再需要手动创建对象,而是自动注入bean对象
        // SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(this.getCLass().getClassLoader().getResource('1.xml'));
        Element rootElement = document.getRootElement();
        String name = rootElement.element("name").getText();
        String age = rootElement.element("age").getText();

        System.out.printIn(name + ":" + age)
    }

}

若要管理第三方bean对象, 建议对这些bean进行集中分类配置, 可以通过 @Configuration注解 声明配置类

@Configuration //声明为配置类
public class commonConfig {

    // 声明第三方bean
    // 将当前方法的返回值交给IOC容器管理,成为bean对象
    @Bean  
    public SAXReader saxReader(DeptServer deptServer){
        // 第三方bean依赖其他的bean对象, 可以通过形参声明, 
        // springboot会根据类型自动注入对象
        System.out.printIn(deptServer);
        return new SAXReader();
    }

    // 还可以继续声明其他bean
}
@SpringBootTest
class TliasWebManagementApplicationTests {

    // 使用时注入bean
    @Autowired
    private SAXReader saxReader;
    
    @Test
    public void testThirdBean() throws Exception {
        Document document = saxReader.read(this.getCLass().getClassLoader().getResource('1.xml'));
        Element rootElement = document.getRootElement();
        String name = rootElement.element("name").getText();
        String age = rootElement.element("age").getText();

        System.out.printIn(name + ":" + age)
    }

}

  1. 项目中自定义的对象, 使用@Componet及其衍生注解, 即可交给IOC容器管理
  2. 项目引用的第三方对象, 使用 @Bean注解, 交给IOC容器管理

SpringBoot原理

Spring Boot框架简化Spring配置的核心就是 起步依赖 和 自动配置

  1. Spring家族的框架都是基于Spring Framework框架运行的,
  2. 直接基于Speing Framework进行项目开发, 需要我们进行大量的依赖引入和配置, 这个过程非常繁琐,
  3. 所以Spring又推出了Spring Boot框架来简化Spring Frameword的配置,
  4. 让我们可以专注于业务的实现, 减少框架层面的配置

起步依赖

如果使用spring框架开发, 需要自己下载用到的依赖, 还要管理依赖的版本

使用springboot开发, 只需要引入web开发的起步依赖, 就完成了依赖的配置

  1. 起步依赖的原理, 就是maven的依赖传递, 只要引入起步依赖, 与其相关的依赖也会被引入
  2. 并且项目中依赖的版本也会由起步依赖统一管理, 不会出现版本冲突的问题

自动配置

Springboot的自动配置就是当spring容器启动后, 我们自己定义的bean对象, 还有一些内置的配置类和bean对象就自动创建并存入到ioc容器中, 不需要我们手动去声明, 就可以注入使用, 从而简化开发, 省去了繁琐的配置操作

自动配置的关键: 如何把pom.xml中依赖的jar包中的配置类自动的加载到ICO容器中?

实现方案

自动配置的核心就是包扫描, 想要实现自动配置, 只需要让spring扫描到依赖包, spring就会自动把依赖包的配置类交给IOC容器管理

方案1: 在启动类中, 使用@ComponentScan() 注解修改组件扫描的范围, 把第三方包添加到组件扫描的范围内

  1. 实际开发中会使用很多第三方包, 如果都要手动添加, 需要频繁修改, 并不合适

方案2: 使用 @import 导入的类会被Spring加载到IOC容器中, 支持多种导入形式

  1. 使用导入类的方式完成自动配置, 我们要清楚的知道第三方依赖所用到的配置类和bean对象, 还是繁琐

方案3: 使用第三方提供的@EnableXxxx注解

  1. 第三方依赖包的作者, 肯定比我们更加清楚, 依赖包中使用到了哪些配置类,
  2. 所以作者会自己封装@EnableXxxx注解, 注解中使用@import注解导入使用到的配置类和bean对象
  3. 我们只需要使用作者提供的 @EnableXxxx注解, 就可以完成依赖的自动配置, 把依赖交给IOC容器管理

源码跟踪

@Conditional注解

原理总结

  1. 实现自动装配的核心注解是 @EnableAutoConfiguration
  2. @EnableAutoConfiguration 注解 封装了 @Import注解
  3. @Import注解 引入了自动配置类,
  4. 自动配置类 实现了selectImport方法,
  5. selectImport方法会读取jar包的两份配置文件
  6. 配置文件中 有很多自动配置类
  7. 满足装配条件的自动配置类会被方法返回, 最终被IOC容器管理

自定义starter

  1. 官方起步依赖命名: spring-boot-starter-功能:版本
  2. 第三方起步依赖命名: 功能-spring-boot-starter:版本

实现步骤

1.创建aliyun-oss-spring-boot-starte模块

<?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>
        // 引入自动配置模块
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2.创建 aliyun-oss-spring-boot-auticonfigure 模块, 该模块要实现自动配置

<?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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>

        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>

</project>

3.引入文件, 并且改造部分代码

package com.aliyun.oss;

import org.springframework.boot.context.properties.ConfigurationProperties;

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

    // 手动提供get/set方法 替换 @Data注解
    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
}
package com.aliyun.oss;

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
/**
 * 阿里云 OSS 工具类
 * @Component 和 @Autowired 不能使用
 */
public class AliOSSUtils {
    // 阿里云参数配置对象
    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的路径返回
    }

}

4.定义自动配置类

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) //把类交给IOC容器管理
public class AliOSSAutoConfiguration {

    @Bean // 把对象交给IOC容器管理
    public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){
        AliOSSUtils aliOSSUtils = new AliOSSUtils();
        aliOSSUtils.setAliOSSProperties(aliOSSProperties);
        return aliOSSUtils;
    }

}

5.定义自动加载文件

右键resources -> new -> Directory -> META-INF/spring

右键 META-INF/spring -> new File -> 文件名 -> ok

文件名: org.springframework.boot.autoconfigure.AutoConfiguration.imports

6.以后使用阿里云oss只需要引入我们自定义的起步依赖就可以了

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId></artifactId>
    <version>0.0.1-SNAPSHOT</version>
 </dependency>
#阿里云OSS
aliyun:
  oss:
    endpoint: https://oss-cn-beijing.aliyuncs.com
    accessKeyId: LTAI5tFE6zMbdaLyhSvNM9J1
    accessKeySecret: jeHMl9EBnCOErmomdgKrZrmCKMcKTt
    bucketName: tlias-web-practice
@RestController
public class UploadController {

    // 注入自定义依赖中的工具类
    @Autowired
    private AliOSSUtils aliOSSUtils;

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

}

技术归类

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

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

相关文章

19、Python如何读写excel文件

在数据处理和分析时&#xff0c;经常使用Excel&#xff0c;而手动操作Excel可能非常繁琐和耗时。Python提供了许多强大的库和工具&#xff0c;可以方便地操作Excel文件。 在Python标准库中是不支持Excel读写的&#xff0c;我们要安装第三方库来实现。 在Python中操作Excel有多…

设计一个高质量的API接口:提升应用性能的关键步骤

在当今的软件开发世界中&#xff0c;API&#xff08;应用程序编程接口&#xff09;接口扮演着至关重要的角色。一个设计精良的API不仅能够提高开发效率&#xff0c;还能提升用户体验&#xff0c;并确保系统的可扩展性和安全性。本文将探讨如何设计一个高质量的API接口&#xff…

Golang | Leetcode Golang题解之第412题Fizz Buzz

题目&#xff1a; 题解&#xff1a; func fizzBuzz(n int) (ans []string) {for i : 1; i < n; i {sb : &strings.Builder{}if i%3 0 {sb.WriteString("Fizz")}if i%5 0 {sb.WriteString("Buzz")}if sb.Len() 0 {sb.WriteString(strconv.Itoa(i…

Davinci 大数据可视化分析

Davinci 大数据可视化分析 一、Davinci 架构设计1.1 Davinci定义1.2 Davinci 应用场景 二、Davinci 安装部署2.1 部署规划2.2 前置环境准备2.3 Davinci部署2.3.1 物料准备2.3.2 安装配置 2.4 环境变量配置2.5 初始化数据库2.5.1 创建数据库及用户 2.5.2 建表2.6 初始化配置 三、…

开源免费的NAS系统-TrueNAS CORE搭建和使用(保姆级教程)

TrueNAS CORE说明 TrueNASCORE(以前称为 FreeNAS)是世界上最受欢迎的存储操作系统,因为它使您能够构建自己的专业级存储系统,用于各种数据密集型应用程序,而无需任何软件成本。只需将其安装到硬件或虚拟机上,即可体验开源存储的真正存储自由。 TrueNAS提供了CORE和Ente…

如何用python构建简单神经网络?

今天&#xff0c;我们将运用Python来搭建一个简单的神经网络模型&#xff01;并深入浅出地探索其背后的运作原理。 多输入 提及神经网络时&#xff0c;我们可以将其视为一个高度灵活的函数来理解和应用。 为了做出准确的预测&#xff0c;我们需要构建能够同时组合多个输入的…

吸浮毛宠物空气净化器推荐,希喂、小米、有哈宠物空气净化器测评

养猫需谨慎&#xff0c;不然就要做猫奴一辈子啦&#xff01;上次堂妹来我家住几天&#xff0c;刚开始还担心和猫处不来&#xff0c;不敢去摸它&#xff0c;走的时候已经约好下次来看它的时间&#xff0c;笑死我了。毕竟猫咪这么可爱&#xff0c;很少有人可以抵抗它的魅力。 这不…

Zabbix 2024 中国峰会在上海举办,Databuff 携最业界领先研发成果重磅亮相

9月13日&#xff0c;Zabbix中国峰会在上海圆满结束。会上共进行了18场技术演讲&#xff0c;共有超过500人参加了本次盛会。 大会开始&#xff0c;Zabbix创始人Alexei Vladishev介绍了Zabbix7.0新功能以及未来的发展蓝图。 随后&#xff0c;乘云数字CEO向成钢分享了《如何打造开…

JVM 调优篇7 调优案例4- 线程溢出

一 线程溢出 1.1 报错信息 每个 Java 线程都需要占用一定的内存空间&#xff0c;当 JVM 向底层操作系统请求创建一个新的 native 线程时&#xff0c;如果没有足够的资源分配就会报此类错误。报错信息&#xff1a;java.lang.outofmemoryError:unable to create new Native Thr…

集群软件在linux上的安装

前置准备 为了保证各个服务器之间的正常通信&#xff0c;要完成集群化环境的前置准备&#xff0c;包括创建多台虚拟机&#xff0c;配置主机名映射&#xff0c;SSH免密登录等等。 配置多个虚拟机 配置多台Linux虚拟机 安装集群化软件&#xff0c;首要条件就是要有多台Linux服务…

web基础—dvwa靶场(四)​File Inclusion

File Inclusion(文件包含) 有些 web 应用程序允许用户指定直接文件流的输入&#xff0c;或允许用户将文件上载到服务器。稍后 web 应用程序访问 web 应用程序上下文中用户提供的输入。通过这样种操作&#xff0c;web 应用程序允许恶意文件执行。 如果选择要包含的文件是目标计…

【系统方案】智慧园区数字园区整体解决全套方案(PPT,Word原件等)

智慧园区建设要点可归纳为以下几点&#xff1a; 基础设施建设&#xff1a;构建高速、稳定的网络基础设施&#xff0c;部署物联网设备&#xff0c;实现园区内设备的互联互通&#xff0c;为智慧化应用提供基础支撑。 数据平台建设&#xff1a;建立统一的数据中心&#xff0c;整合…

Linux中安装maven

Linux中安装maven 1.下载2.安装3.配置环境变量4.maven相关配置 1.下载 下载地址&#xff1a;https://maven.apache.org/download.cgi 2.安装 指定位置上传压缩包&#xff1a; 解压&#xff1a; tar -zxvf apache-maven-3.9.5-bin.tar.gz修改解压缩后的文件名: mv apac…

c++刷题

17.电话号码的组合 来源于题解思路&#xff1a; 继承 CC14 KiKi设计类继承 #include <iostream> #include <memory> using namespace std; class Shape{ private:int x;int y; };class Rectangle:public Shape { public:Rectangle(int length,int width):Shape…

从AI应用排行榜选择AI产品(9月)

2024年9月13日&#xff0c;OpenAI公司宣布推出其全新的AI模型&#xff1a;o1&#xff0c;在数学、编程和科学问题的解决处理能力上取得了显著进步。该模型通过自我对弈强化学习&#xff08;Self-play RL&#xff09;和思维链&#xff08;Chain of Thought, CoT&#xff09;技术…

[C语言]连子棋游戏

文章目录 一、前言二、游戏思路三、游戏方法1、初始化2、判断胜利3、交互4、电脑下棋 四、核心方法说明1、初始化游戏2、销毁棋盘3、显示游戏4、电脑下棋5、用户下棋6、判断游戏状态7、游戏交互 五、游戏效果展示与源码分享1、游戏效果2、源代码 一、前言 对于指针和数组理解尚…

Qt:智能指针QScopedPointer 的使用(以及如何写一个QScopedPointer )

前言 本文讲述QScopedPointer 的使用&#xff0c;以及自己如何写一个QScopedPointer . 正文 QScopedPointer 的常用方法 以下是 QScopedPointer 的一些常用方法及其详细说明&#xff1a; 构造函数&#xff1a; QScopedPointer<T> ptr(new T);用于创建一个 QScopedPoi…

【C/C++】涉及string类的经典OJ编程题

【C/C】涉及string类的经典OJ编程题 一. 把字符串转化成整数&#xff08;atoi&#xff09;解法一&#xff1a;&#xff08;不用long&#xff09;完整代码&#xff1a;解法二&#xff1a;&#xff08;用long&#xff09; 二.字符串相加代码实现&#xff08;含注释&#xff09;&a…

【RabbitMQ】RabbitMQ 概述

RabbitMQ 概述 前⾔什么是MQMQ的作⽤为什么选择RabbitMQ1. Kafka2. RocketMQ3. RabbitMQ 前⾔ Rabbit 也是⼀个公司名. MQ ( message queue ) 消息队列 的意思 , RabbitMQ 是 Rabbit 企业下的⼀个消息队列产品. RabbitMQ 是⼀个实现了 AMQP 的 消息队列 服务,是当前主流的消息…

IBM中国研发部裁员:全球化背景下的中国IT产业挑战与机遇

文章目录 每日一句正能量前言整体分析人才发展裁员对中国IT人才市场的影响&#xff1a;IT从业者提升竞争力的策略&#xff1a; 产业未来后记 每日一句正能量 一切美好的事物都是曲折地接近自己的目标&#xff0c;一切笔直都是骗人的&#xff0c;所有真理都是弯曲的&#xff0c;…