JavaWeb学习路线(10)—— 关于SpringBoot的原理

news2024/9/27 7:15:57

一、配置文件优先级

在Springboot框架三s种配置文件的格式

  • application.properties
  • application.yml
  • application.yaml

Springboot是支持多配置文件的,所以当我们使用两种配置文件配置相同参数时,Springboot会执行哪一个配置文件呢?这就是SpringBoot的配置优先级。

(一)另外的配置:

  • Java系统属性配置 -Dserver.port=9000
  • 命令行参数 --server.port=9001
    在这里插入图片描述

(二)配置优先级:命令行参数 > Java系统属性 > properties配置文件 > yml配置文件 > yaml配置文件


二、Bean管理

(一)获取Bean

前提: 默认情况下,Spring项目启动时,会把Bean都创建好放在IOC容器中。(主要针对于 默认的单例非延迟加载的bean而言)

  • 获取方式一:根据name获取bean Object getBean(String name)
  • 获取方式二:根据类型获取bean <T> T getBean(Class<T> requiredType)
  • 获取方式三:根据name获取bean(带类型转换)<T> T getBean(String name, Class<T> requiredType)
@SpringBootTest
public class GetBeanTest {
    //1、注入IOC容器
    @Autowired
    private ApplicationContext applicationContext;

    @Test
    public void getBeanTest(){
        //根据Bean对象的Name获取
        LoginController controller = (LoginController) applicationContext.getBean("loginController");
        System.out.println(controller);

        //根据类型进行获取
        LoginController controller1 = applicationContext.getBean(LoginController.class);
        System.out.println(controller1);

        //根据名称和类型进行获取
        LoginController controller2 = applicationContext.getBean("loginController",LoginController.class);
        System.out.println(controller2);
    }
}

打印输出结果:
com.zengoo.controller.LoginController@7e31062c
com.zengoo.controller.LoginController@7e31062c
com.zengoo.controller.LoginController@7e31062c

(二)Bean的作用域

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

作用域说明
singleton容器内同名称的bean只有一个实例(默认)
prototype每次使用该 bean 时会创建新的实例(非单例)
request每个请求范围内会创建新的实例
session每个会话范围内会创建新的实例
application每个应用范围内会创建新的实例

2、配置作用域——使用注解 @Scope

@Scope("prototype")
@RestController
@RequestMapping("/api")
public class xxxController{
}

通过再一次多次获取Bean对象,可以预见每次取得的Bean对象是不同的。

//输出结果
com.zengoo.controller.LoginController@316d30ad
com.zengoo.controller.LoginController@3ea75b05
com.zengoo.controller.LoginController@30d5e37c

3、延迟Bean对象初始化 —— 使用 @Lazy

@Lazy这个注解可以延迟一个Bean对象初始化,一直到它第一次被使用才启动初始化方法。

@Lazy
@RestController
@RequestMapping("/api")
public class LoginController {
    @Autowired
    public UserService userService;
    
    @PostMapping("/login")
    public int login(@RequestBody User user){
        User u = userService.login(user);
        return u !=null?200:-1;
    }
}

4、注意事项

  • 默认 singletonbean,在容器启动时被创建,可以使用 @Lazy注解来延迟初始化。
  • prototypebean,每一次使用该 bean的时候都会创建一个新的实例。
  • 实际开发中,绝大部分的Bean对象是单例的,也就是说绝大部分Bean不需要配置 scope属性。

(三)第三方Bean

1、概念: 如果要管理的bean对象来自第三方,是无法使用@Component及衍生注解声明bean的,就需要用到 @Bean注解。

2、使用方式

(1)直接定义在启动类中(不推荐)

@SpringBootApplication
public class SpringbooWebConfig2Application{
	//用代理的形式,返回新的Bean对象
	@Bean  //可以通过 name/value 属性重命名
	public SAXReader saxReader(){
		return new SAXReader;
	}
}

(2)定义配置类——集中管理

@Configuration
public class CommonConfig {
	@Bean
	public SAXReader saxReader(){
		return new SAXReader;
	}
}

3、注意事项

  • 通过@Bean注解的 name/valule 属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。
  • 若第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器根据类型自动装配。

三、SpringBoot原理

(一)起步依赖

  • 实现原理: 依赖传递,一个起步依赖包含大多数都需要的依赖(例如spring-web,spring-webmvc等等)。

(二)自动配置

  • 概念: SpringBoot的自动装配就是当spring容器启动后,一些配置类,bean对象自动存入IOC容器,不需要开发者手动声明。
  • 实现原理:
    • 实现方案一: 当我们引入第三方包时,IOC容器需要@Component注解并且开启注解扫描@ComponentScan({"com.xx","com.xxxx})
    • 实现方案二: 使用注解@Import导入第三方包,该注解可以导入普通类配置类ImportSelector 接口实现类,使用@Enablexxxx注解获取bean对象,其中已经封装好了@Import
//1、@Import({TokenParser.class, HeaderConfig.class})
//2、@Import({MyImportSelector.class})
@SpringBootApplication
public class SpringbootWebConfig2Application{
}

普通类

public class TokenParser{
}

配置类

@Component
@Configuration
public class HeaderConfig{
}

ImportSelector类

//作用:将所有数组中的所有全类名匹配对象交给Spring容器管理
public class MyImportSelector implements ImportSelector {
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		return new String[]{"xxx.xxx.xxxx"}
	}
}
  • SpringBoot的自动配置原理
    • 1、Springboot通过@SpringBootApplication注解封装了@SpringBootConfiguration(封装了@Configuration,作用是声明当前类为配置类),@ComponentScan(组件扫描),@EnableAutoConfiguration(加载自动配置实现)
    • 2、@EnableAutoConfiguration通过读取两个配置文件信息,通过@Import(AutoConfigurationImportSelector.class)加载到IOC容器中管理。
    • 3、各个第三方bean会通过@Bean声明bean对象,通过Conditional衍生出的各子注解为bean对象加载到IOC容器增加条件。
      • @ConditionalOnClass:判断环境中含有对应的类,才注册bean到IOC容器
      • @ConditionalOnMissingBean:判断环境中没有对应的bean(根据 类型 — value名称 — name 进行判断),才注册bean到IOC
      • @ConditionalOnProperty:判断配置文件中有对应属性和值(属性名 —— namehavingValue —— 属性值),才注册bean到IOC容器

关于@Conditional的衍生注解

在这里插入图片描述

读取的两个配置文件

在这里插入图片描述
(三)自定义起步依赖

1、自定义过程

(1)创建新的依赖模块(仅支持管理依赖)

模块1:aliyun-oss-boot-starter

在这里插入图片描述

(2)自动配置模块

模块2:aliuyn-oss-spring-boot-autoconfigure

在这里插入图片描述
(3)启动依赖中加入自动配置类与其他依赖

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliuyn-oss-spring-boot-autoconfigure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>        
        <!--        SpringWeb依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--    lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        

(4)自动配置模块中,引入阿里云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>

(5)准备阿里云OSS工具类

@Data	//lombok方法,为成员变量添加get/set方法
public class AliOSSUtils {
    @Autowired
    private AliOSSProperties properties;

    public void upload(MultipartFile file) throws com.aliyuncs.exceptions.ClientException {
        String endpoint = properties.getEndpoint();
        String accessKey = properties.getAccessKey();
        String accessKeySecret = properties.getAccessKeySecret();
        String bucketName = properties.getBucketName();

        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        String objectName = "";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            String content = "Hello OSS";
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

(6)准备阿里云OSS信息类

@Data
//扫描以 “aliyun.oss”为前缀的配置文件属性(是application.yml中的属性)
@ConfigurationProperties(prefix = "aliyun.oss")	
public class AliOSSProperties {
    private String endpoint;
    private String accessKey;
    private String accessKeySecret;
    private String bucketName;
}

(7)准备阿里云OSS自动配置类

@Configuration	//声明配置类
@EnableConfigurationProperties(AliOSSProperties.class)	//声明自动配置的对象
public class AliOSSAutoConfiguration {
    public AliOSSUtils getAliOSSUtils(AliOSSProperties aliOSSProperties){
        AliOSSUtils aliOSSUtils = new AliOSSUtils();
        aliOSSUtils.setProperties(aliOSSProperties);
        return aliOSSUtils;
    }
}

(8)准备自动配置文件
在这里插入图片描述
(9)使用自定义的启动依赖

步骤一:引入起步依赖

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

步骤二:准备数据配置类

aliyun:
	oss:
		endpoint: xxx,
		accessKeyId: xxx,
		accessKeySecret: xxx,
		bucketName: xxx

步骤三: 直接使用阿里云OSS工具类

@Autowired
private AliOSSUtils aliOSSUtils;

@PostMapping("/upload")
public String upload(MultipartFile image) throws Exception{
	String url = aliOSSUtils.upload(image);
	return url;
}

总结自定义起步依赖

  • 两个模块:starter模块 和 autoconfigure模块
    • starter模块用来引入autoconfigure模块,不进行具体操作。
    • autoconfigure模块

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

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

相关文章

FFmpeg5.0源码阅读—— avcodec_open2

摘要&#xff1a;本文主要描述了FFmpeg中用于打开编解码器接口avcodec_open2大致流程的具体调用流程&#xff0c;详细描述了该接口被调用时所作的具体工作。   关键字&#xff1a;ffmpeg、avcodec_open2大致流程   注意&#xff1a;读者需要了解FFmpeg的基本使用流程&#…

SpringMVC (一) 什么是SpringMVC

一、回顾MVC 1.1、什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式&#xff0c;MVC是一种架构模式。…

在 ZBrush、Maya 和 Substance 3D Painter 中制作后世界末日女性角色

今天瑞云渲染小编给大家带来了蒂亚戈布兰道 (Thiago Brandao) 分享的设计极其精细后世界末日女性角色背后的秘密&#xff0c;解释了复杂的纹理处理过程&#xff0c;并谈到了创造逼真的面部特征。 介绍 我的名字是蒂亚戈-布兰道。我来自巴西&#xff0c;目前住在这里。从小&…

【AJAX】原生AJAX

目录 一、AJAX的使用场景 二、原生的AJAX 三、HTTP &#xff1a; 1、原生AJAX GET请求 1、原生AJAX POST请求 四、总结 一、AJAX的使用场景 1、页面不刷新的情况下&#xff0c;浏览器等搜索框输入某关键字出现多个搜索选择内容,如下图所示&#xff1a; 2、登录、注册界面输…

前端JS如何实现对复杂文本进行句子分割,将每句话拆分出来?

文章目录 切割句子背景简介前端如何使用NLP&#xff1f;技术实现 切割句子背景简介 开发中遇到一种场景&#xff0c;在做文本翻译这块需求时&#xff0c;需要对输入的原文进行一句一句话的拆分出来&#xff0c;传给后台&#xff0c;获取每句话的翻译结果&#xff0c;便于实现页…

clickhouse系统日志引起的root目录磁盘满的问题处理

问题及追踪 对于生产环境&#xff0c;尤其是配置较低的生产环境&#xff0c;一定要注意资源的使用 今天就遇到一个问题&#xff0c;服务器磁盘接近满了&#xff0c;部署的平台服务异常&#xff0c;无法提供服务 简单说一下客户环境&#xff1a;客户只有老的Windows server 服…

hydra的简单使用

Hydra是一款开源的暴力PJ工具&#xff0c;集成在kali当中。 参数功能-l指定用户名-p指定密码-L指定用户名字典-P指定密码字典-C指定所用格式为“user:password”的字典文件-en null&#xff0c;表示尝试空密码-es same&#xff0c;把用户名本身当做密码进行尝试-er 反向&#…

哈工大计算机网络课程网络层协议详解之:距离向量路由算法与层次化路由算法

文章目录 距离向量路由算法Bellman-Ford算法举例距离向量路由算法 层次化路由算法层次化路由AS示例自治系统间&#xff08;Inter-AS&#xff09;路由任务 在上一节中我们介绍了路由算法中的链路状态路由算法&#xff0c;介绍它基于Dijkstra算法来实现&#xff0c;同时分析了其缺…

Jmeter接口测试断言详解

目录 前言&#xff1a; 响应断言 Apply to (响应断言的应用范围) 要测试的响应字段(可通过取样器结果查看) 响应断言&#xff1a;模式匹配 Json断言 前言&#xff1a; 在JMeter中进行接口测试时&#xff0c;断言是一个非常重要的概念。断言允许我们验证接口的响应是否符…

十七、docker学习-docker-compose安装nginx反向代理

compose安装nginx反向代理 IDEA安装docker插件 idea安装docker插件。Dockerfile、docker-compose.yml文件大部分内容会有提示信息。方便开发人员编写配置文件。 https://plugins.jetbrains.com/plugin/7724-docker/versions基础镜像 docker pull 1.21.0-alpine docker pull…

一文读懂SQL中的Aggregate(聚合) 函数和Scalar(标准)函数

目录 前言&#xff1a; 一、SQL Aggregate 函数 1、AVG() 函数 2、count()函数 3、MAX() 函数 4、MIN() 函数 5、SUM() 函数 6、SQL GROUP BY 语法 7、SQL HAVING 子句 8、SQL EXISTS 运算符 9、SQL UNION 操作符 二、SQL Scalar 函数 1、SQL UCASE() 函数 2、SQ…

Swift 周报 第三十二期

文章目录 前言新闻和社区现已提供新的设计资源visionOS SDK 现已发布 提案Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组自主整理周报的第二十三期&#xff0c;每个模块已初步成型。各位读者如果有好的提议&#xff0c;欢迎在文末留言。 欢迎投稿或推荐内容。…

力扣 -- 174. 地下城游戏

题目链接&#xff1a;174. 地下城游戏 - 力扣&#xff08;LeetCode&#xff09; 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 参考代码&#xff1a; class Solution { public:int calculateMinimumHP(vector&…

【上海海事大学806】23上岸学姐经验分享

今天很荣幸请到了一位23上岸上海海事大学的学姐来给大家做一期经验分享&#xff01;&#xff01;&#xff01;我之前也有做过关于上海海事大学806的一些真题解析以及重点勾画&#xff0c;希望能帮到大家&#xff0c; 一、学姐经验分享 很荣幸你能看到我的考研经验分享&#x…

第七章 版本控制器——git

第七章 版本控制器——git 一、git的历史二、git的特点与发展1、git的特点2、git与github 二、git的安装与注册1、git的安装2、git的使用&#xff08;1&#xff09;github注册&#xff08;2&#xff09;创建远端仓库&#xff08;3&#xff09;将远端仓库镜像复制到本地仓库指令…

LIS实验室信息管理系统功能模块(Oracle数据库、Client/Server架构)

一、系统框架简介 1、技术框架 &#xff08;1&#xff09;总体框架&#xff1a; ♦SaaS架构的Client/Server应用 ♦服务可伸缩&#xff0c;多服务协同 ♦服务可拆分&#xff0c;功能易扩展 &#xff08;2&#xff09;技术细节&#xff1a; ♦体系结构&#xff1a;Client/Serv…

零基础小白暑假QT实训1

一.前言 今天就要开始暑假短学期的实训了&#xff0c;本来课堂也要求记笔记&#xff0c;这里我就开始分享我将来五天的学习过程吧。 二.QT安装过程 首先&#xff0c;提供一下我的链接&#xff1a; 本来上传到我的阿里云盘了的&#xff0c;结果压缩包不给分享&#xff0c;抱歉…

互联网高可用架构探讨 | 京东云技术团队

高可用指标与问题 高可用&#xff0c;英文单词High Availability&#xff0c;缩写HA&#xff0c;它是分布式系统架构设计中一个重要的度量。业界通常用多个9来衡量系统的可用性&#xff0c;如下表&#xff1a; 既然有可用率&#xff0c;有一定会存在不可用的情况。系统宕机一般…

【动态规划上分复盘】下降路径最小和|礼物的最大价值

欢迎 前言一、动态规划五部曲二、下降路径最小和思路&#xff1a;动态规划解法具体代码如下 三、礼物的最大价值思路&#xff1a;动态规划具体代码如下: 总结 前言 本文主要讲述动态规划思路的下降路径最小和以及礼物的最大价值两道题。 一、动态规划五部曲 1.确定状态表示&a…

61. 旋转链表

61. 旋转链表 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 旋转链表 https://leetcode.cn/problems/rotate-list/ 完成情况&#xff1a; 解题思路&#xff1a; 参考代码&#xff1a; package 西湖算法题解_…