Spring Boot注解详解

启动与配置

@SpringBootApplication - 主启动类
作用:这是 Spring Boot 项目的入口注解,用于标记主启动类(包含main方法的类),是一个 “组合注解”,整合了以下 3 个核心注解的功能:

  • @SpringBootConfiguration:本质是@Configuration,标记该类为配置类,可定义 Bean;
  • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制(核心);
  • @ComponentScan:自动扫描当前包及其子包下的@Component/@Service/@Controller等注解的类,注册为 Bean。

举例:

1
2
3
4
5
6
7
8
// 主启动类,放在项目根包下(如com.example.demo),确保@ComponentScan能扫描所有子包
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// 启动Spring Boot应用,加载上下文
SpringApplication.run(DemoApplication.class, args);
}
}

关键参数与扩展

参数 作用
scanBasePackages 指定 @ComponentScan 的扫描包(默认扫描当前类所在包),解决包路径不一致问题
exclude 排除特定的自动配置类(如exclude = DataSourceAutoConfiguration.class)
excludeName 按类名排除自动配置类(字符串形式)

举例:

1
2
3
4
5
6
7
8
9
@SpringBootApplication(
scanBasePackages = "com.example", // 扫描com.example下所有包
exclude = DataSourceAutoConfiguration.class // 禁用数据源自动配置
)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

@EnableAutoConfiguration - 启用自动配置
作用:Spring Boot 的 “自动配置” 核心注解,会根据项目中引入的依赖(如spring-boot-starter-web),自动配置相关的 Bean(如 DispatcherServlet、Tomcat),无需手动编写 XML 或 Java 配置。

底层原理:

  • Spring Boot 内置了大量自动配置类(如WebMvcAutoConfiguration、DataSourceAutoConfiguration),位于org.springframework.boot.autoconfigure包下;
  • @EnableAutoConfiguration会加载这些自动配置类,结合条件注解(如下文的@ConditionalOnClass)判断是否生效。

注意事项

  • 通常不单独使用,而是通过@SpringBootApplication间接使用;
  • 可通过spring-boot-starter-parent的spring.autoconfigure.exclude配置全局排除自动配置类。

@ConfigurationProperties - 配置属性绑定
作用:将外部配置文件(如application.yml/application.properties)中的属性批量绑定到 Java 类的字段上,替代零散的@Value注解,适合配置项较多的场景(如数据源、第三方服务配置)。

核心用法

关键参数 作用
prefix 指定配置属性的前缀(核心),绑定该前缀下的所有属性
ignoreInvalidFields 忽略类型不匹配的字段(默认 false,不匹配会抛异常)
ignoreUnknownFields 忽略配置文件中不存在于类中的字段(默认 true)

举例:

1
2
3
4
5
6
7
# 自定义配置,前缀为"app.user"
app:
user:
name: 张三
age: 20
address: 北京
hobbies: [篮球, 足球]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 方式1:配合@Component,直接注册为Bean
@Component
@ConfigurationProperties(prefix = "app.user")
public class UserProperties {
// 字段名与配置文件中前缀后的属性名一致(name → app.user.name)
private String name;
private Integer age;
private String address;
private List<String> hobbies;

// 必须有getter/setter(Spring通过setter赋值)
// toString() 省略
}
@RestController
public class TestController {
// 注入绑定好的配置Bean
@Autowired
private UserProperties userProperties;

@GetMapping("/config")
public String getConfig() {
return userProperties.toString();
// 返回:UserProperties{name='张三', age=20, address='北京', hobbies=[篮球, 足球]}
}
}

扩展用法(@EnableConfigurationProperties):

1
2
3
4
5
@Configuration
@EnableConfigurationProperties(UserProperties.class)
public class Config {
// 无需@Component,UserProperties也会被注册为Bean
}

@PropertySource - 属性源
作用:加载非默认配置文件(默认是 application.yml/properties),比如自定义的myconfig.properties/myconfig.yml,补充默认配置的不足。

关键限制

  • 默认仅支持.properties文件(不支持.yml),加载.yml需自定义YamlPropertySourceFactory;
  • 加载的配置优先级低于默认配置文件(可通过ignoreResourceNotFound = true忽略文件不存在的异常)。

完整示例
步骤 1:创建自定义配置文件(src/main/resources/myconfig.properties)

1
2
3
# 自定义配置
custom.name=李四
custom.age=25

步骤 2:加载并绑定配置

1
2
3
4
5
6
7
8
9
@Component
@PropertySource(value = "classpath:myconfig.properties", ignoreResourceNotFound = true)
@ConfigurationProperties(prefix = "custom")
public class CustomProperties {
private String name;
private Integer age;

// getter/setter/toString 省略
}

步骤 3:使用

1
2
3
4
5
6
7
8
9
10
@RestController
public class TestController {
@Autowired
private CustomProperties customProperties;

@GetMapping("/custom")
public String getCustomConfig() {
return customProperties.toString(); // 返回:CustomProperties{name='李四', age=25}
}
}

加载 YAML 文件的扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 自定义YAML属性源工厂
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(name != null ? name : resource.getResource().getFilename(), properties);
}
}

// 使用自定义工厂加载yml文件
@Component
@PropertySource(value = "classpath:myconfig.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "custom")
public class CustomProperties {
// 同上
}

条件注解

@ConditionalOnClass
作用:当类路径中存在指定的类时,当前配置类 / Bean 才会生效,常用于 “引入某个依赖后才加载相关配置”。

举例:

1
2
3
4
5
6
7
8
9
10
11
12
// 只有引入了Redis依赖(存在RedisTemplate类),才加载该配置
@Configuration
@ConditionalOnClass(RedisTemplate.class)
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 配置序列化器...
return template;
}
}

注意

  • 参数可传多个类(@ConditionalOnClass({A.class, B.class})),需所有类都存在才生效;
  • 若类路径中无指定类,该配置类不会被加载,避免 “找不到类” 的异常。

@ConditionalOnMissingBean
作用:当Spring 容器中不存在指定的 Bean时,当前 Bean 才会被创建,常用于 “默认配置”(用户未自定义时使用默认 Bean)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class UserServiceConfig {
// 只有容器中没有UserService类型的Bean时,才创建这个默认Bean
@Bean
@ConditionalOnMissingBean(UserService.class)
public UserService defaultUserService() {
return new DefaultUserService();
}
}

// 若用户自定义了UserService Bean,默认Bean不会被创建
@Service
public class CustomUserService implements UserService {
// 自定义实现
}

关键参数

参数 作用
value 指定要判断的 Bean 类型(如UserService.class)
name 指定要判断的 Bean 名称(如”userService”)
type 按类名字符串指定(避免类不存在的编译错误,如type = “redis.clients.jedis.Jedis”)

@ConditionalOnProperty
作用:根据配置文件中的属性值判断是否生效,常用于 “开关式配置”(如是否启用某个功能)。

关键参数

参数 作用
prefix 属性前缀
name 属性名(可多个)
havingValue 属性需要匹配的值(默认匹配非空值)
matchIfMissing 配置中无该属性时是否匹配(默认 false)

举例:
步骤 1:配置文件(application.yml)

1
2
3
4
5
# 功能开关
app:
feature:
redis: true # 启用Redis功能
cache: false # 禁用缓存功能

步骤 2:条件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 只有app.feature.redis=true时,该配置才生效
@Configuration
@ConditionalOnProperty(
prefix = "app.feature",
name = "redis",
havingValue = "true",
matchIfMissing = false // 无该配置时不生效
)
public class RedisFeatureConfig {
// Redis相关Bean配置...
}

// 只有app.feature.cache=true时生效(当前配置为false,该配置不加载)
@Configuration
@ConditionalOnProperty(prefix = "app.feature", name = "cache")
public class CacheFeatureConfig {
// 缓存相关Bean配置...
}

@ConditionalOnWebApplication
作用:当应用是Web 应用时生效,分为 3 种类型:

  • Type.SERVLET:传统 Servlet Web 应用(Spring MVC);
  • Type.REACTIVE:响应式 Web 应用(Spring WebFlux);
  • Type.ANY:任意 Web 应用(默认)。

举例:

1
2
3
4
5
6
// 仅在Servlet类型的Web应用中生效(Spring MVC项目)
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class WebMvcConfig {
// 配置拦截器、视图解析器等WebMVC相关Bean...
}

@ConditionalOnExpression
作用:支持SpEL 表达式(Spring 表达式语言)判断,灵活性最高,可组合多个条件。

举例:

1
2
3
4
5
6
// 当app.feature.redis=true且app.env=prod时生效
@Configuration
@ConditionalOnExpression("${app.feature.redis:true} and 'prod'.equals(${app.env})")
public class ProdRedisConfig {
// 生产环境Redis配置...
}

常用 SpEL 语法

  • ${key}:读取配置属性;
  • and/or/not:逻辑运算;
  • eq/ne/gt/lt:比较运算;
  • isEmpty()/contains():集合 / 字符串操作。

总结

  • 启动与配置注解核心
    • @SpringBootApplication是主启动类入口,整合了配置类、自动配置、包扫描三大功能;
    • @ConfigurationProperties批量绑定配置文件属性,替代@Value,适合多配置项场景;
    • @PropertySource加载自定义配置文件,默认支持 properties,需扩展才能加载 yml。
  • 条件注解核心
    • @ConditionalOnClass:依赖存在才加载配置,避免类缺失异常;
    • @ConditionalOnMissingBean:用户未自定义 Bean 时加载默认实现,支持扩展;
    • @ConditionalOnProperty:通过配置开关控制功能是否启用,最常用的条件注解;
    • 条件注解是 Spring Boot “约定大于配置” 的核心,实现了配置的按需加载和灵活扩展。