当前位置: 首页 > article >正文

[Java]SpringBoot能力进阶

配置优先级

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.kler.cn/a/314040.html

相关文章:

  • 【ACM出版】第四届信号处理与通信技术国际学术会议(SPCT 2024)
  • redis7.x源码分析:(1) sds动态字符串
  • Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
  • uniCloud云对象调用第三方接口,根据IP获取用户归属地的免费API接口,亲测可用
  • 结构体是否包含特定类型的成员变量
  • Linux 系统管理和监控命令---- auditctl命令
  • 九章云极DataCanvas公司荣获2024年服贸会“科技创新服务示范案例”
  • 面向对象例题之例题的特性
  • 在Android中fragment的生命周期
  • 校园场景物体检测系统源码分享
  • Jboss Administration Console弱⼝令
  • macOS平台TensorFlow环境安装
  • 老程序员的数字游戏开发笔记(二) —— 直接开始一个Godot项目
  • SQLServer日期和时间类型
  • SpringCloud从零开始简单搭建 - JDK17
  • 基于python上门维修预约服务数据分析系统
  • Apache SeaTunnel Zeta引擎源码解析(三) Server端接收任务的执行流程
  • 【案例72】Apache检测到目标 URL 存在 http host 头攻击漏洞的解决方案
  • 如何安装1Panel面板并架设一个静态网站
  • Kubernetes从零到精通(11-CNI网络插件)
  • ppt组织结构图怎么增加分支?
  • 【python 类型注解详解】
  • 基于神经网络的光线追踪
  • 2024最新!!!iOS高级面试题,全!(一)
  • STM32(十五):I2C通信
  • PostgreSQL数据库怎么生成一个随机的UUID