javaweb-Day12-Springboot原理

TJCcc 发布于 2 天前 3 次阅读


一、Spring Boot 配置优先级

Spring Boot 配置来源很多,常见的简化优先级为:

命令行参数 > Java 系统属性 > .properties 文件 > .yml 文件 > .yaml 文件

示例:

java -jar demo.jar --server.port=8081
java -Dserver.port=8082 -jar demo.jar
# application.properties
server.port=8083
# application.yml
server:
  port: 8084
# application.yaml
server:
  port: 8085

如果同时存在,最终生效的是 命令行参数中的 8081


补充:更完整的配置优先级

实际开发中,Spring Boot 配置优先级大致如下,从高到低:

优先级配置来源
命令行参数
Java 系统属性
操作系统环境变量
application-{profile}.properties
application-{profile}.yml
application.properties
application.yml
application.yaml
默认配置

此外,配置文件位置也会影响优先级:

项目根目录/config/  >  项目根目录/  >  classpath:/config/  >  classpath:/

同一个目录下:

application.properties  >  application.yml  >  application.yaml

注意:.yml.yaml 本质相同,实际项目中不建议同时使用,容易造成混乱。


二、Bean 的管理

1. 获取 Bean

Spring 容器启动后,可以通过 ApplicationContext 获取 Bean。

@SpringBootTest
class BeanTest {

    @Autowired
    private ApplicationContext applicationContext;

    @Test
    void testGetBean() {
        // 1. 根据类型获取
        UserService userService = applicationContext.getBean(UserService.class);

        // 2. 根据名称获取,需要强制转换
        UserService userService2 = (UserService) applicationContext.getBean("userService");

        // 3. 根据名称 + 类型获取
        UserService userService3 = applicationContext.getBean("userService", UserService.class);
    }
}

2. Bean 的作用域

Spring Boot 中 Bean 默认是单例的,也可以手动指定作用域。

作用域说明
singleton默认,整个容器中只有一个实例
prototype每次获取都会创建新的实例
request每次 HTTP 请求创建一个实例
session每个 HTTP 会话创建一个实例
application每个 ServletContext 创建一个实例
websocket每个 WebSocket 创建一个实例

示例:

@Component
@Scope("singleton")
public class SingletonBean {
}

@Component
@Scope("prototype")
public class PrototypeBean {
}

也可以使用注解:

@RequestScope
@Component
public class RequestBean {
}

@SessionScope
@Component
public class SessionBean {
}

注意:单例 Bean 中注入原型 Bean 时,原型 Bean 不会每次重新创建,原因是单例 Bean 只会注入一次。如果需要每次获取新的原型 Bean,可以使用 @LookupObjectProvider

3. 第三方 Bean

第三方类通常无法直接使用 @Component 注解,需要通过 @Configuration + @Bean 手动注册。

@Configuration
public class ThirdPartyBeanConfig {

    // 注册 RestTemplate
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // 注册自定义 Bean,并自动注入已有 Bean
    @Bean
    public MyService myService(UserMapper userMapper) {
        return new MyService(userMapper);
    }

    // 指定 Bean 名称
    @Bean("myDataSource")
    public DataSource dataSource() {
        return new DruidDataSource();
    }
}

也可以在 @Bean 中指定初始化和销毁方法:

@Bean(initMethod = "init", destroyMethod = "destroy")
public ThirdPartyClient thirdPartyClient() {
    return new ThirdPartyClient();
}

三、Spring Boot 原理

1. 起步依赖 starter

Spring Boot 通过 starter 将一组常用的依赖打包在一起,简化依赖管理。

例如引入 Web 起步依赖:

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

这一个依赖会自动传递引入:

  • spring-webmvc
  • spring-web
  • tomcat
  • jackson
  • spring-boot-starter
  • 等等

常见的 starter:

Starter作用
spring-boot-starter-webWeb 开发,内置 Tomcat
spring-boot-starter-test测试相关依赖
spring-boot-starter-jdbcJDBC 数据库操作
spring-boot-starter-data-redisRedis 集成
mybatis-spring-boot-starterMyBatis 集成

优点:

  • 不用手动解决依赖版本冲突
  • 版本统一由 Spring Boot 的 BOM 管理
  • 开箱即用,减少配置

2. 自动配置

Spring Boot 的核心之一是自动配置,它可以根据依赖和配置自动装配 Bean。

@SpringBootApplication

启动类上的 @SpringBootApplication 是一个组合注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}

三个核心注解作用:

注解作用
@SpringBootConfiguration标识这是一个配置类
@EnableAutoConfiguration开启自动配置
@ComponentScan扫描当前包及其子包中的组件

自动配置流程

@EnableAutoConfiguration 会导入自动配置选择器:

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

AutoConfigurationImportSelector 会读取自动配置类列表:

  • Spring Boot 2.7 及以后:
    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • Spring Boot 2.7 以前:
    META-INF/spring.factories 中的 EnableAutoConfiguration

自动配置类示例:

org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

条件注解

自动配置并不是全部生效,而是通过条件注解按需加载。

常用条件注解:

注解作用
@ConditionalOnClass类路径下存在指定类时生效
@ConditionalOnMissingBean容器中不存在指定 Bean 时生效
@ConditionalOnProperty配置属性满足条件时生效
@ConditionalOnWebApplication当前是 Web 应用时生效

示例:

@Configuration
@ConditionalOnClass({DispatcherServlet.class})
@ConditionalOnWebApplication
public class WebMvcAutoConfiguration {
    // 只有存在 DispatcherServlet 并且是 Web 应用时才生效
}

排除自动配置

如果不想使用某个自动配置,可以排除:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

也可以在配置文件中排除:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

小结

  1. 配置优先级:命令行参数 > Java 系统属性 > 配置文件,其中 .properties 优先于 .yml.yaml
  2. Bean 管理:可以通过 ApplicationContext 获取 Bean;默认单例,可设置为原型或其他作用域;第三方类通过 @Configuration + @Bean 注册。
  3. Spring Boot 原理:starter 简化依赖管理;@EnableAutoConfiguration 配合条件注解实现按需自动配置。
唯有极致沉淀,才能造就辉煌。
最后更新于 2026-08-22