122.【SpringBoot - 再刷 - 基础入门 - 01】

news2024/9/19 15:13:16

SpringBoot2 核心技术

  • (一)、SpringBoot核心技术入门
    • 1.Spring能做什么?
      • 1.1、Spring 的能力
      • 1.2、Spring的生态
      • 1.3、Spring5重大升级
        • 1.3.1、响应式编程
        • 1.3.2、内部源码设计
    • 2.为什么用SpringBoot
      • 2.1、SpringBoot优点
      • 2.2、SpringBoot缺点
    • 3.时代背景
      • 3.1、微服务
      • 3.2、分布式的困难
      • 3.3、云原生
    • 4.如何学习SpringBoot
      • 4.1、查看官方文档
  • (二)、SpringBoot2入门
      • 1.系统要求
        • 1.1、maven设置
      • 2.HelloWord
        • 2.1、创建maven工程
        • 2.3、创建主程序
        • 2.4、编写业务
        • 2.5、RestController源码 ⭐
        • 2.6、测试是否成功
        • 2.7、简化配置 ⭐⭐
        • 2.8、简化打包 ⭐⭐⭐
  • (三)、了解SpringBoot自动配置原理
    • 1.SpringBoot特点
      • 1.1、依赖管理
        • (1).父项目控制版本依赖 (自动版本仲裁机制)
        • (2).自定义依赖版本
        • (3).starter场景启动器
        • (4).版本仲裁
      • 1.2、自动配置
        • (1).自动配备 Tomcat
        • (2).自动配备 SpringMVC
        • (3). 自动配备 常用组件
        • (4).默认的包结构 (修改默认扫描路径) ⭐
        • (5).自动配置 配置有用默认值
        • (6).按需加载自动配置项
    • 2.IOC容器功能
      • 2.1、组件添加
        • (1).@Configuration
        • (2).@Bean、@Component、@Controller、@Service、@Repository
        • (3).@ComponentScan、@Import
        • (4).@Conditional
    • 2.2、原生配置文件引入 (只能放在类级别的注解上)
        • (1). 尚未使用 @ImportResource
        • (2). 引用 @ImportResource
      • 2.3、配置绑定
        • (1).@ConfigurationProperties (第一种)
        • (2).@EnableConfigurationProperties (第二种)
    • 3.自动配置原理入门
      • 3.1、引导加载自动配置类
        • (1). @SpringBootConfiguration
        • (2). @ComponentScan
        • (3).@EnableAutoConfiguration
          • (3.1).@AutoConfigurationPackage (自定义注入组件)
          • (3.2).@Import({AutoConfigurationImportSelector.class}) (官方注入)
      • 3.2、按需开启自动配置项
      • 3.3、 修改默认配置
      • 3.4、 总结
      • 3.5、最佳实践
    • 4.开发技巧
      • 4.1 lombok 技术
      • 4.2 devtools 技术

(一)、SpringBoot核心技术入门

官方文档: https://www.yuque.com/atguigu/springboot/na3pfd

1.Spring能做什么?

1.1、Spring 的能力

在这里插入图片描述

1.2、Spring的生态

https://spring.io/projects/spring-boot

覆盖了:
web开发
数据访问
安全控制
分布式
消息服务
移动开发
批处理

1.3、Spring5重大升级

1.3.1、响应式编程

在这里插入图片描述

1.3.2、内部源码设计

基于Java8的一些新特性,如:接口默认实现。重新设计源码架构。

2.为什么用SpringBoot

2.1、SpringBoot优点

Create stand-alone Spring applications
○ 创建独立Spring应用

Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌web服务器

Provide opinionated ‘starter’ dependencies to simplify your build configuration
自动starter依赖,简化构建配置

Automatically configure Spring and 3rd party libraries whenever possible
自动配置Spring以及第三方功能

Provide production-ready features such as metrics, health checks, and externalized configuration
提供生产级别的监控、健康检查及外部化配置

Absolutely no code generation and no requirement for XML configuration
○ 无代码生成、无需编写XML

SpringBoot的底层是Spring.Spring的底层是Java。

2.2、SpringBoot缺点

● 人称版本帝,迭代快,需要时刻关注变化

封装太深,内部原理复杂,不容易精通

3.时代背景

3.1、微服务

● 微服务是一种架构风格
● 一个应用拆分为一组小型服务
● 每个服务运行在自己的进程内,也就是可独立部署和升级
● 服务之间使用轻量级HTTP交互
● 服务围绕业务功能拆分
● 可以由全自动部署机制独立部署
● 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术

3.2、分布式的困难

● 远程调用
● 服务发现
● 负载均衡
● 服务容错
● 配置管理
● 服务监控
● 链路追踪
● 日志管理
● 任务调度
● …

3.3、云原生

原生应用如何上云。 Cloud Native

上云的困难

● 服务自愈
● 弹性伸缩
● 服务隔离
● 自动化部署
● 灰度发布
● 流量治理
● …

上云的解决

在这里插入图片描述

4.如何学习SpringBoot

4.1、查看官方文档

SpringBoot 2.4.13 官方文档: https://docs.spring.io/spring-boot/docs/2.4.13/reference/html//
在这里插入图片描述
在这里插入图片描述

(二)、SpringBoot2入门

1.系统要求

● Java 8 & 兼容java14 .
● Maven 3.3+
● idea 2019.1.2

1.1、maven设置

1.查看自己的Maven版本:

mvn -version

在这里插入图片描述
2.打开自己的Maven配置文件
在这里插入图片描述

// 使用阿里云的镜像进行下载
<mirrors>
      <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      </mirror>
  </mirrors>
 
 // 使用jdk1.8进行编译
  <profiles>
         <profile>
              <id>jdk-1.8</id>
              <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
              </activation>
              <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
              </properties>
         </profile>
  </profiles>

2.HelloWord

2.1、创建maven工程

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>

2.3、创建主程序

/**
 * 主程序类
 * @SpringBootApplication:这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {

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

2.4、编写业务

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String handle01(){
        return "Hello, Spring Boot 2!";
    }

}

2.5、RestController源码 ⭐

@Controller + @ResponseBody = @RestController

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller ⭐⭐
@ResponseBody ⭐⭐
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

2.6、测试是否成功

在这里插入图片描述

2.7、简化配置 ⭐⭐

有一个统一的配置文件 : application.properties
在这里插入图片描述

官方配置选项: 2.4.3 application.properties配置选项

在这里插入图片描述
在这里插入图片描述

2.8、简化打包 ⭐⭐⭐

在以前我们如果需要打包一个jar包是非常繁琐的,我们需要先写入配置文件,然后打包成war包,再然后利用第三方工具进行将war包转换为jar包

现在我们SpringBoot给我们提供了一款便捷的打包工具插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

然后我们在终端输入: mvn package 即可打包成功!!!

(三)、了解SpringBoot自动配置原理

1.SpringBoot特点

1.1、依赖管理

在实际开发中: 父项目是为了做依赖管理的,也就是统一管理我们软件开发的版本号。

(1).父项目控制版本依赖 (自动版本仲裁机制)

依赖管理    
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>

他的父项目
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.3.4.RELEASE</version>
  </parent>

几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

他的父项目的父项目几乎指定了所有版本信息

在这里插入图片描述

(2).自定义依赖版本

在日常工作和开发中我们会遇到SpringBoot自动生成的很多版本和我们实际需要的版本不一致的问题,我们只需要在当前的的Maven依赖管理文件中新增如下版本指定即可覆盖原有的不合实际的版本。

1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置

    <properties>
        <mysql.version>5.16.4</mysql.version>
    </properties>

在这里插入图片描述

(3).starter场景启动器

1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>

(4).版本仲裁

1、引入依赖默认都可以不写版本
2、引入非版本仲裁的jar,要写版本号。

1.2、自动配置

(1).自动配备 Tomcat

引入Tomcat、配置Tomcat。

我们引入的web启动器中,底层帮我们引入了tomcat
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
点击查看web启动器的源码,发现以下Tomcat配置文件
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.4.3</version>
      <scope>compile</scope>
    </dependency>

在这里插入图片描述

(2).自动配备 SpringMVC

web启动器的源码依然帮助我们自动配备了webMVC

  • 引入SpringMVC全套组件
  • 自动配好SpringMVC常用组件(功能)
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.4</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.4</version>
      <scope>compile</scope>
    </dependency>

(3). 自动配备 常用组件

启动类返回的是IOC容器,我们查看这个IOC容器中的组件名都有哪些,就自动帮助我们配备了哪些组件。

package com.jsxs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }
    }
}

在这里插入图片描述

(4).默认的包结构 (修改默认扫描路径) ⭐

  • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
com
 +- example
     +- myapplication
         +- Application.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java
  • 无需以前的包扫描配置

  • 想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.atguigu")或者@ComponentScan 指定扫描路径

1.在主程序的启动类上进行手动添加要扫描的位置,我们点开SpringBootApplication的注解源码发现里面存在一个value为scanBasePackages
我们只需要在这里指定扫描包的位置路径即可。
@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan = @SpringBootApplication
package com.jsxs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication(scanBasePackages="com.jsxs")
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }
    }
}

在这里插入图片描述

(5).自动配置 配置有用默认值

application.properties: 默认的配置其实都是映射到一个类上的

在这里插入图片描述
比如配置端口号映射的类名是 : ServerProperties.java
在这里插入图片描述

(6).按需加载自动配置项

  • 非常多的starter
  • 引入了哪些场景这个场景的自动配置才会开启
  • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

如果我们查看源码的时候爆红,不是因为我们哪里写错了,而是我们的SpringBoot是按需配置的,没有使用上(使用依赖)就会爆红。
在这里插入图片描述

2.IOC容器功能

2.1、组件添加

(1).@Configuration

  • 基本使用
  • Full模式与Lite模式
    • 示例
    • 最佳实战
      • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
      • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

1.我们使用SpringMVC的时候如何进行组件添加的

在resources目录下创建 beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 1.指定我们的人类实体类并赋值id   -->
    <bean id="user01" class="com.jsxs.bean.User">
        <!-- 2.给我们实体类进行默认赋值的操作       -->
        <property name="name" value="李明"></property>
        <property name="age" value="12"></property>
    </bean>
    <!-- 3.指定宠物实体类并赋值id   -->
    <bean id="cat" class="com.jsxs.bean.Pet">
        <property name="name" value="哈吉米"></property>
    </bean>
</beans>

2.现在我们省去了配置文件,直接使用@Configuration注解即可

package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Configuration(proxyBeanMethods=false)  // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
public class MyConfig {

    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

在这里插入图片描述

  1. 什么时候用到Full模式或List模式呢?

组件依赖必须使用Full模式默认。其他默认是否Lite模式。通俗的讲就是如果这个容器下面没人用了我们就设置成false,如果仍然有人是用的话,我们就设置成true。

  • 区别: 设置成fasle会跳过检查是否容器中已经存在,提升性能。

列子: 用户拥有容器中注册的哈吉米猫,我们要使用FULL模式,因为要保证用户有的是唯一的,即用户拥有的哈吉米猫和容器中组件的哈吉米猫是一样的。

User.java

package com.jsxs.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:11
 * @PackageName:com.jsxs.bean
 * @ClassName: User
 * @Description: TODO
 * @Version 1.0
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String name;
    private int age;
    //
    private Pet pet;
}

config.java 设置为FULL模式

package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Configuration(proxyBeanMethods=true)// 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
public class MyConfig {

    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

在这里插入图片描述

(2).@Bean、@Component、@Controller、@Service、@Repository

1.SpringMVC提供的这些注解,只要在SpringBoot扫描包的范围内仍然可以进行注册组件。

1. @Bean  注册配置类组件
2. @Component 除了配置类组件不能使用,其余万能
3. @Controller 控制层组件
4. @Service 业务层组件
5. @Repository 实体类层组件  

(3).@ComponentScan、@Import

1.@ComponentScan 组件

通过这个注解我们可以手动的更改SpringBoot默认的扫描路径。

2. @Import

用法:
1. @imoort 用于放在容器中组件类上。
用途
2. @imoort 用于给容器中导入 自定义组件或第三方组件 
结论
3. @import引入组件和手动添加组件结果都添加到容器中去了,但是获取到的组件名有点区别: 引入的获得的名字是全限定名,手动的不是全限定名。
package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Import({User.class})  ⭐⭐
@Configuration(proxyBeanMethods=true)  // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
public class MyConfig {

    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

package com.jsxs;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import com.jsxs.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }
        // 3.从IOC容器中获取组件,结果为true证明是单实列的。Bean是一个组件
        Pet tom1 = run.getBean("tom", Pet.class);
        Pet tom2 = run.getBean("tom", Pet.class);
        System.out.println("组件"+(tom1==tom2));  // == 比较的是地址
        // 4.配置类(类名)也是一个组件
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean); // 如果能打印出来,就署名我们通过类名获取一个组件成功
        // 5.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
        User user1 = bean.user01();
        User user2 = bean.user01();
        System.out.println(user1==user2); //如果被代理就为true,不被代理就为false
        // 6.验证Full模式
        User user01 = (User) run.getBean("user01",User.class); //从容器中获取user
        Pet pet = user01.getPet();
        Pet tom = run.getBean("tom", Pet.class);  //假如不是代理的,那么在这里就会重新生成一个bean,如果是代理的就不会重新生成
        System.out.println("验证Full:"+(pet==tom));

        // 7.验证import引入组件 
        String[] type = run.getBeanNamesForType(User.class);//根据类型进行获取组件
        System.out.println("======="); ⭐⭐⭐
        for (String s : type) {
            System.out.println(s);
        }

    }
}

在这里插入图片描述

(4).@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入

在这里插入图片描述

1.当组件中存在某个组件的时候才执行注册

1.作用域: 类上或者方法上。
假如标注到方法上,当这个条件注解为真的时候,这个方法上的注册才生效。当标注到类上的时候,当条件为假的时候,这个类上的所有方法都不生效(也就不会注入到IOC)@ConditionalOnBean(name = "tom") // 当整个IOC容器中存在tom这个容器,我们就注册user01这个组件否则不注册

我们这里对tom容器进行了注释,也就是说IOC容器中不存在tom容器了。

package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Import({User.class})
@Configuration(proxyBeanMethods=true)  // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
public class MyConfig {

    @ConditionalOnBean(name = "tom") // 当整个IOC容器中存在tom这个容器,我们就注册user01这个组件否则不注册
    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
//    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

package com.jsxs;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import com.jsxs.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }

        // 1.测试容器中是否有tom这个组件
        boolean flag = run.containsBean("tom");
        System.out.println("IOC容器是否有tom容器:"+flag);
        boolean b = run.containsBean("user01");
        System.out.println("IOC容器中是否有user01这个容器:"+b);
    }
}

在这里插入图片描述

  1. 当容器中没有指定的组件的时候才执行
package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Import({User.class})
@Configuration(proxyBeanMethods=true)  // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
@ConditionalOnMissingBean(name = "tom") // 当整个IOC容器中存在tom这个容器,我们就注册user01这个组件否则不注册
public class MyConfig {


    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
//    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

package com.jsxs;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import com.jsxs.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }

        // 1.测试容器中是否有tom这个组件
        boolean flag = run.containsBean("tom");
        System.out.println("IOC容器是否有tom容器:"+flag);
        boolean b = run.containsBean("user01");
        System.out.println("IOC容器中是否有user01这个容器:"+b);

    }
}

在这里插入图片描述

2.2、原生配置文件引入 (只能放在类级别的注解上)

1.作用:
	我们使用SpringBoot框架之后,SpringMvc支持的beans.xml配置文件不会被SpringBoot进行解析,这时候我们想要SpringBoot帮助我们解析beans.xml
2.用法:
文件的话,我们可以在任意一个IOC容器组件类上进行@ImportResource()即可
这个注解放在任意一个IOC容器类组件上即可。(放一个即可)

classpath: 指的是resource目录下
@ImportResource("classpath:beans.xml")

(1). 尚未使用 @ImportResource

/resource/benas.xml: 我们对id名进行修改(避嫌),进行查找是否存在这两个组件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 1.指定我们的人类实体类并赋值id   -->
    <bean id="haha" class="com.jsxs.bean.User">
        <!-- 2.给我们实体类进行默认赋值的操作       -->
        <property name="name" value="李明"></property>
        <property name="age" value="12"></property>
    </bean>
    <!-- 3.指定宠物实体类并赋值id   -->
    <bean id="hehe" class="com.jsxs.bean.Pet">
        <property name="name" value="哈吉米"></property>
    </bean>
</beans>

查询结果:是查询不到的。因为SpringBoot识别不了这个beans.xml文件
在这里插入图片描述

(2). 引用 @ImportResource

package com.jsxs.config;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Import({User.class})
@Configuration(proxyBeanMethods=true)  // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
//@ConditionalOnMissingBean(name = "tom") // 当整个IOC容器中存在tom这个容器,我们就注册user01这个组件否则不注册
@ImportResource("classpath:beans.xml")
public class MyConfig {


    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

package com.jsxs;

import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import com.jsxs.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:53
 * @PackageName:com.jsxs
 * @ClassName: MainSpringApplication
 * @Description: TODO
 * @Version 1.0
 */
@SpringBootApplication
public class MainSpringApplication {
    public static void main(String[] args) {
        // 1.返回的是我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainSpringApplication.class, args);
        // 2.我们查看IOC容器里面都有哪些组件
        String[] benas = run.getBeanDefinitionNames();
        for (String bena : benas) {
            System.out.println(bena);
        }
        // 9.@ImportResource ⭐
        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha "+haha+" " + "hehe " +hehe);
    }
}

在这里插入图片描述

2.3、配置绑定

就是实体类通过配置文件进行赋值

切记:任何一个注解都只对IOC容器生效,如果注解没有加入IOC容器中去,那么会爆红且报错

在这里插入图片描述

(1).@ConfigurationProperties (第一种)

前缀指的是 .属性 前面的那个单词就是前缀。

我们在使用@ConfigurationProperties注解的时候,指定的前缀就是 .属性前面的那个单词。

1.application.properties

server.port=8080

mycar.brand=BYD
mycar.price=1200

2.进行配置绑定

package com.jsxs.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Repository;

/**
 * @Author Jsxs
 * @Date 2023/7/1 16:34
 * @PackageName:com.jsxs.bean
 * @ClassName: Car
 * @Description: TODO  只会在IOC容器中的组件,才会拥有SprngBoot提供的强大功能
 * @Version 1.0
 */
@Data
@Repository
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "mycar")  // 添加上前缀

public class Car {
    private String brand;
    private Integer price;
}

3.注解的源码:

这里prefix与value互为别名

package org.springframework.boot.context.properties;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
    @AliasFor("prefix")
    String value() default "";

    @AliasFor("value")
    String prefix() default "";

    boolean ignoreInvalidFields() default false;

    boolean ignoreUnknownFields() default true;
}

4.controller进行测试

package com.jsxs.controller;

import com.jsxs.bean.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @Author Jsxs
 * @Date 2023/7/1 9:55
 * @PackageName:com.jsxs.controller
 * @ClassName: IndexController
 * @Description: TODO
 * @Version 1.0
 */
@RestController
public class IndexController {

    @Resource
    Car car;

    @RequestMapping("/hello")
    public String hello(){
        return "hello";
    }

    @RequestMapping("/car")
    public Car car(){
        return car;
    }
}

在这里插入图片描述

(2).@EnableConfigurationProperties (第二种)

1. 前提条件
	(1).实体类上可以不用加@Compont注入到IOC容器中
	(2).实体类上需要指定配置绑定的前缀 @ConfigurationProperties(prefix = "mycar")  // 添加上前缀
	(3).@EnableConfigurationProperties(实体类.class) 需要放在任意IOC容器组件类上
2.
@EnableConfigurationProperties(实体类.class) = 配置绑定 + @Component依赖注入
3.使用场景:
当我们引用第三方默认的配置时候,第三方在实体类上没有添加@Component注入到IOC容器的时候,我们需要使用第二种方式。

实体类

package com.jsxs.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Repository;

/**
 * @Author Jsxs
 * @Date 2023/7/1 16:34
 * @PackageName:com.jsxs.bean
 * @ClassName: Car
 * @Description: TODO  只会在IOC容器中的组件,才会拥有SprngBoot提供的强大功能
 * @Version 1.0
 */
@Data
//@Repository   这次把IOC容器组件给去掉 ⭐
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "mycar")  // 添加上前缀  ⭐⭐

public class Car {
    private String brand;
    private Integer price;
}

配置类上

package com.jsxs.config;

import com.jsxs.bean.Car;
import com.jsxs.bean.Pet;
import com.jsxs.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.*;

/**
 * @Author Jsxs
 * @Date 2023/7/1 12:30
 * @PackageName:com.config
 * @ClassName: MyConfig
 * @Description: TODO 1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实列的,
 * @Description: TODO 2.配置类(类名)本身也是一个组件,即在这个列子中有三个组件并不是俩个。
 * @Description: TODO 3.@Configuration(proxyBeanMethods=true)代理bean,也就是无论外部调用多少次实列都是一样的即单列。否则不是单实列
 *                          Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *                          Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *                          组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 * @Version 1.0
 */
@Import({User.class})
@Configuration(proxyBeanMethods=true) ⭐⭐⭐ // 告诉SpringBoot这是一个配置类,相当于以前的配置文件 beans.xml
//@ConditionalOnMissingBean(name = "tom") // 当整个IOC容器中存在tom这个容器,我们就注册user01这个组件否则不注册
@ImportResource("classpath:beans.xml")
@EnableConfigurationProperties(Car.class) ⭐⭐⭐⭐ // 1.开启配置绑定功能。 2.把Car这个属性自动注入到容器中
public class MyConfig {


    @Bean // 1. 这里相当于我们配置文件中的<bena></bean>标签
    //  2. User对应的是我们配置文件的class非全限定名, user01对应我们配置文件的id
    public User user01() {
        // FULL模式人拥有宠物
        return new User("李明",12,this.cat());
    }
    @Bean("tom")  // 相当于我们配置文件的bean标签
    public Pet cat(){  // Pet指的是calss的非全限定名, cat指定的是id
        return new Pet("哈吉米");
    }
}

在这里插入图片描述

3.自动配置原理入门

3.1、引导加载自动配置类

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}


======================
    

(1). @SpringBootConfiguration

  • @Configuration。代表当前是一个配置类

(2). @ComponentScan

  • 指定扫描哪些,Spring注解;

(3).@EnableAutoConfiguration

1.@EnableAutoConfiguration的合成

1.注解的合成: 
@EnableAutoConfiguration= @AutoConfigurationPackage +  @Import(AutoConfigurationImportSelector.class)
2.
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
(3.1).@AutoConfigurationPackage (自定义注入组件)

自动配置包?指定了默认的包规则 (即我们主启动类下的包)

@Import(AutoConfigurationPackages.Registrar.class)  //给容器中导入一个组件
public @interface AutoConfigurationPackage {}

//利用 Registrar 给容器中导入一系列组件
//将指定的一个包下的所有组件导入进来?MainApplication(主启动类) 所在包下。
  1. 我们点开Registar.class这个源代码发现里面存在两个方法
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }

        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
        }
    }

在星星的位置打上断点,发现我们的元数据上的路径在主启动类上。

在这里插入图片描述
我们通过计算的到: 导入的是我们主启动类下所在的包中的组件。
在这里插入图片描述

(3.2).@Import({AutoConfigurationImportSelector.class}) (官方注入)
  1. 点进@Import({AutoConfigurationImportSelector.class})找到
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
4、从META-INF/spring.factories位置来加载一个文件。
	默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
 ⭐⭐⭐   spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

这里导入的130个包就是 spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面的META-INF/spring.factories
在这里插入图片描述

文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

3.2、按需开启自动配置项

虽然我们130个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。

在这里插入图片描述
按需开启自动配置的原理是: 按条件注入
在这里插入图片描述

3.3、 修改默认配置

        @Bean
		@ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
            //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
            //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}
给容器中加入了文件上传解析器;

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

	@Bean
	@ConditionalOnMissingBean  //假如没有的时候自动创建,用户创建了就不自动创建了。
	public CharacterEncodingFilter characterEncodingFilter() {
    }

3.4、 总结

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration(自动装配文件) —> 组件 —> xxxxProperties (实体类)里面拿值 ----> application.properties (主配置文件)

3.5、最佳实践

  • 引入场景依赖
    • https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
  • 查看自动配置了哪些(选做)
    • 自己分析,引入场景对应的自动配置一般都生效了
    • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
  • 是否需要修改
    • 参照文档修改配置项
      • https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties
      • 自己分析。xxxxProperties绑定了配置文件的哪些。
  • 自定义加入或者替换组件
    • @Bean、@Component。。。
    • 自定义器 XXXXXCustomizer;

4.开发技巧

4.1 lombok 技术

1. 可以帮助我们配置实体类
2. 拥有@Slf4j 日志配置注解

===============================简化JavaBean开发===================================
@NoArgsConstructor
//@AllArgsConstructor
@Data
@ToString
@EqualsAndHashCode
public class User {

    private String name;
    private Integer age;

    private Pet pet;

    public User(String name,Integer age){
        this.name = name;
        this.age = age;
    }


}


================================简化日志开发===================================
@Slf4j
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(@RequestParam("name") String name){
        
        log.info("请求进来了....");
        
        return "Hello, Spring Boot 2!"+"你好:"+name;
    }
}

在这里插入图片描述

4.2 devtools 技术

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

项目或者页面修改以后:Ctrl+F9

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

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

相关文章

github克隆代码加速

https://www.gitclone.com/gogs/ 只需要在正常的git clone后的URL里&#xff0c;嵌入gitclone.com即可快速clone 举例&#xff1a; #原地址 git clone https://github.com/SpringSource/Spring-framework #新地址 git clone https://gitclone.com/github.com/SpringSource/…

2023年出货量预计增长75%,谁在领跑规模化量产赛道?

2023年将成为一个分水岭&#xff0c;中国智能驾驶市场已经进入了下一个竞争周期&#xff0c;卷&#xff0c;难 成为了智驾赛道新的关键词&#xff0c;对各赛道的供应商来说&#xff0c;未来几年将是比拼规模化与降本。 对各级供应商来说&#xff0c;产品规模化量产&#xff0c…

【二叉树part07】| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236.二叉树的最近公共祖先

目录 &#x1f388;LeetCode530.二叉搜索树的最小绝对差 &#x1f388;LeetCode501.二叉搜索树中的众数 &#x1f388;LeetCode236.二叉树的最近公共祖先 &#x1f388;LeetCode530.二叉搜索树的最小绝对差 链接&#xff1a;530.二叉树的最小绝对差 给你一个二叉搜索树的根…

主成分分析系列(二)为什么特征向量是主成分

在主成分分析系列&#xff08;一&#xff09;概览及数据为何要中心化这篇文章中介绍了PCA算法的大概想法及数据为何要中心化&#xff0c;在这篇文章具体推导PCA算法的过程。 1. 首先 PCA 最原始的想法是&#xff1a; 设 V \mathbf{V} V 为 d {d} d 维 线性空间&#xff08;即…

python项目导入导出依赖包

1. 导出所有依赖包 进入项目路径&#xff0c;执行以下命令&#xff1a; pip freeze > requirements.txt然后在当前目录是可以看到生成“requirements.txt”文件&#xff0c;可以打开看看&#xff0c;会发现有很多个包信息&#xff0c;其实这里是把你当前python环境的所有包…

如何编写一个含有抄底信号的副图指标

如果你作为通达信软件源代码的程序维护员&#xff0c;如何编写一个含有抄底提示的副图指标&#xff1f;请看下面的的示例教程。(python语言) python # 导入所需的库 import talib # 计算移动平均线 def moving_average(data, period): ma talib.SMA(data, timeperiodperio…

江苏一学霸,高考居然考了0分,老师们调取了监控后,才发现真相

学校里的学霸&#xff0c;李明&#xff0c;一直以来都是大家羡慕的对象。他聪明伶俐&#xff0c;学习优秀&#xff0c;每次考试都能轻松取得满分。而这次高考&#xff0c;他的成绩却让所有人大跌眼镜——零分&#xff01;这个让人难以置信的结果引发了全校师生的困惑和疑问。 在…

还傻傻搞不懂MySQL事务隔离级别么(图文并茂,保证你懂!)

本文首发于公众号【看点代码再上班】&#xff0c;欢迎围观&#xff0c;第一时间获取最新文章。 原文&#xff1a;还傻傻搞不懂MySQL事务隔离级别么&#xff08;图文并茂&#xff0c;保证你懂&#xff01;&#xff09; 大家好&#xff0c;我是tin&#xff0c;这是我的第25篇原创…

MySQL 服务无法启动

问题场景&#xff1a; 启动mysql&#xff1a;net start mysql 临时解决办法&#xff1a; tasklist| findstr "mysql"taskkill/f /t /im mysqld.exemysqld --console重新打开一个cmd测试连接mysql 永久解决办法&#xff1a; 找到Mysql的根目录&#xff0c;删除dat…

云原生时代,如何通过极狐GitLab x KubeSphere 构建安全应用?

目录 DevSecOps 是什么&#xff1f;如何帮助我们打造云原生安全生态&#xff1f; 如何寻找云原生 DevSecOps 落地切入点&#xff1f; 第一层&#xff1a;K8s 安全 第二层&#xff1a;容器镜像安全 第三层&#xff1a;应用程序安全 这么多安全功能&#xff0c;如何去实现落…

RISCV Reader笔记_5 RV32A,RV32C

原子指令 RV32A 是 RISCV 支持原子操作的扩展。主要有两种实现方式&#xff1a;内存原子操作&#xff08;AMO&#xff09;&#xff0c;加载保留/条件存储&#xff08;load reserved / store conditional&#xff09; AMO&#xff1a;一个处理器对内存的操作不会被打断&#xf…

数据库建表之外键关联

0前言 摘自某一段记事&#xff1a;   在实际的开发中&#xff0c;必然遇到“编辑操作”&#xff0c;而编辑操作&#xff0c;看似简单&#xff0c;实则其影响面甚广。本着设计的“贯穿性”和逻辑一致性&#xff0c;本文将按照&#xff0c;创建基础表的字段建议&#xff0c;创…

STM32 Proteus UCOSII系统水塔鱼缸水位控制系统-0052

STM32 Proteus UCOSII系统水塔鱼缸水位控制系统-0052 Proteus仿真小实验&#xff1a; STM32 Proteus UCOSII系统水塔鱼缸水位控制系统-0052 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD1602显示器多个按键&#xff08;注水、排水&#xff09;驱动电路电位…

HOT32-复制带随机指针的链表

leetcode原题链接&#xff1a;复制带随机指针的链表 题目描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xf…

企业如何判断是否选择CRM系统?

如今&#xff0c;以客户为中心的观点已经被广泛认可&#xff0c;想要建立以客户为中心的战略离不开CRM客户关系管理系统的应用&#xff0c;企业什么时候需要CRM&#xff1f;附CRM软件的选购指南。当企业出现这4点问题的时候证明是时候部署CRM了。 1.客户资料散乱 通常每个业务…

【结构型设计模式】桥接模式

一、写在前面 桥接模式&#xff08;Bridge&#xff09;&#xff1a;桥接模式是一种结构型设计模式&#xff0c;其目的是将抽象部分和实现部分分离&#xff0c;允许它们可以独立地变化。该模式通过创建一个桥接类&#xff0c;连接抽象和实现&#xff0c;使得它们可以独立地进行…

【前端|CSS系列第3篇】CSS盒模型、浮动及定位

在前端开发中&#xff0c;CSS是一项重要的技术&#xff0c;用于控制网页的样式和布局。在本系列的第三篇文章中&#xff0c;我们将学习CSS的盒模型、浮动以及定位&#xff0c;这些概念和技术在页面布局中起着至关重要的作用。通过本文的学习&#xff0c;希望能够帮助大家更好地…

阿里云远程仓库环境安装

记录一些基本的命令&#xff1a; 一、apt-get&#xff0c;是一条linux命令&#xff0c;适用于deb包管理式的操作系统&#xff08;例如Ubuntu系统&#xff09;&#xff0c;主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。 // 常用命令&#xff1a; ap…

沐风老师3DMAX虚线对象插件Dashed使用方法详解

3DMAX虚线对象插件Dashed教程 Dashed虚线对象插件&#xff0c;用于沿拾取路径创建虚线&#xff08;或实线&#xff09;几何体对象 【主要特点】 -更多实用参数可以调节。 -沿着样条曲线测量距离值&#xff08;如&#xff1a;笔划长度、间距、分段长度等&#xff09;&#xff…

MySql的MVCC_存储引擎_历史_开发模式

概览 一. 多版本并发控制(MVCC)1.概述2.InnoDB的MVCC 二.MySql的存储引擎 一. 多版本并发控制(MVCC) 1.概述 可以认为MVCC是行级锁的一个变种,其在很多情况下避免了加锁操作&#xff0c;因此开销更低。 不同存储引擎的MVCC实现是不同的&#xff0c;但大部分实现了非阻塞的读…