@SpringBootApplication注解干了个啥?
通常使用Spring Boot的应用程序的主类是这样的:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@SpringBootApplication
注解的定义:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
....
}
@SpringBootApplication
注解从它的定义能看出来,是一个组合注解,做了三件事情:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
第一件事情:@SpringBootConfiguration
@SpringBootConfiguration注解同@Configuration,表明这个类可提供Spring Boot应用配置,也就是在这个类中可定义@Bean注解修饰的方法,这些Bean会由Spring容器管理。比如:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
var requestFactory = new OkHttp3ClientHttpRequestFactory();
return new RestTemplate(requestFactory);
}
}
这样restTemplate就是一个被Spring容器管理的Bean了。
第二件事情:@EnableAutoConfiguration
很明显,从名字就能看出来,@EnableAutoConfiguration是用来启用自动配置的。当启用Spring应用上下文的自动配置后,Spring Boot会尝试推测需要哪些Bean,并配置这些Bean。自动配置会基于应用的classpath及自定义的Bean来配置。 比如, 如果classpath里包含tomcat-embedded.jar,会自动配置TomcatServletWebServerFactory Bean。
第三件事情:@ComponentScan
不带参数的@ComponentScan告诉Spring扫描当前包及其所有子包。所以@SpringBootApplication所修饰的主类理应放在最外层包,以保证其下的所有@Component都能被扫描到。
当然也可以通过修改@ComponentScan的basePackages来指定扫描的包,如下:
@ComponentScan(basePackages = "chengco.validation.demo")
使用了@SpringBootApplication之后,@ComponentScan注解已经封装在内部了,所以@SpringBootApplication也提供了scanBasePackages和scanBasePackageClasses来完成相应的功能,比如:
@SpringBootApplication(scanBasePackages = { "chengco.validation.demo" })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
var requestFactory = new OkHttp3ClientHttpRequestFactory();
return new RestTemplate(requestFactory);
}
}