Skip to content

使用 @SpringBootApplication 注解

许多 Spring Boot 开发者喜欢让他们的应用程序包含自动配置、组件扫描,并能在“应用类”上定义额外的配置。使用一个 @SpringBootApplication 注解就可以同时启用这三个特性:

  • @EnableAutoConfiguration: 启用 Spring Boot 的自动配置机制
  • @ComponentScan: 在应用程序所在的包上启用 @Component 扫描(参见最佳实践)。
  • @SpringBootConfiguration: 允许在上下文中注册额外的 Bean 或导入额外的配置类。它是 Spring 标准 @Configuration 的替代方案,有助于在集成测试中探测配置
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 等同于 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
public class MyApplication {

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

}
kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

// 等同于 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
	runApplication<MyApplication>(*args)
}

::: note 注意 @SpringBootApplication 还提供了别名,允许你自定义 @EnableAutoConfiguration@ComponentScan 的属性。 :::

个性化组合(替代方案)

这些特性并非强制捆绑的,你可以根据需要使用它所包含的任何单一特性来替换这个注解。例如,如果你不希望在应用中使用组件扫描或配置属性扫描:

java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Import;

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ SomeConfiguration.class, AnotherConfiguration.class })
public class MyApplication {

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

}
kotlin
import org.springframework.boot.SpringBootConfiguration
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Import

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import(SomeConfiguration::class, AnotherConfiguration::class)
class MyApplication

fun main(args: Array<String>) {
	runApplication<MyApplication>(*args)
}

在这个例子中,MyApplication 与普通的 Spring Boot 应用无异,唯一的区别是:它不会自动探测带有 @Component@ConfigurationProperties 注解的类,所有的用户自定义 Bean 必须通过 @Import 显式导入。


补充教学

1. 为什么推荐将 @SpringBootApplication 放在根包?

正如之前提到的,@ComponentScan 默认扫描当前包及其子包。如果你把启动类放在根包,你就相当于开启了“全量扫描”模式,这对于大多数标准项目来说是最省心的方案。

2. proxyBeanMethods = false 是什么?

在上面的替代方案示例中出现了这个属性。默认情况下(true),Spring 会使用 CGLIB 代理配置类,拦截内部 Bean 方法调用以维持单例(Full 模式)。设置为 false(Lite 模式)后,Spring 不再代理该类,启动速度会略微加快,且内存占用更低,但你不能在类内部通过调用方法来引用另一个 Bean。在云原生和 GraalVM 原生镜像场景下,通常推荐设置为 false

3. 复合注解的优势

@SpringBootApplication 不仅仅是少写三个注解,它代表了一种“约定优于配置”的共识。当你看到此注解时,你立刻就知道这是一个 Spring Boot 应用入口,且遵循标准的加载逻辑,大大降低了团队协作的理解成本。

Based on Spring Framework.