SpringBoot项目都有一个长得很像的启动类:
@SpringBootApplication
public class XxxApplication {
public static void main(String[] args) {
SpringApplication.run(XxxApplication.class, args);
}
}
通过运行这个类的main函数,就能顺利的启动整个springboot项目。
那么,为什么这个类可以启动整个SpringBoot项目?执行run方法之后具体又做了哪些事?
本小节先探究第一个问题,即springboot的启动类特殊在哪?
关键注解SpringBootApplication
让一个类成为“启动类”,关键的注解就是SpringBootApplication,它是一个组合注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
其中最关键的是下面3个注解:
- @SpringBootConfiguration(Configuration)
- @EnableAutoConfiguration
- @ComponentScan
如果我们不想用SpringBootApplication注解,直接使用上面3个注解,也可以把一个类变成启动类。
由此可以看出,SpringBootApplication所实现的效果就是上面3个注解的叠加,因此有必要先探究一下每个注解的具体作用。
SpringBootConfiguration注解
这个注解的内部就是@Configuration,两者是等价的。
Configuration注解的作用是告诉Spring,当前类是一个Spring Ioc容器的配置类,在这个容器的配置类里,任何一个使用了@Bean注解的方法的返回值,都将作为一个被spring管理的bean被注册到Spring容器中:
@Configuration
public class MockConfiguration{
@Bean
public MockService mockService(){
return new MockServiceImpl();
}
}
ComponentScan注解
@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。
默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描,扫描范围是所在类的package及内部的子package。因此,springboot的启动类通常放在项目的根目录下。
我们也可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围。
EnableAutoConfiguration注解
这个注解的作用非常重要,它是实现springboot自动配置功能的关键注解。
相比于SpringMVC,springboot有一个很大的优点是大大简化了配置过程,能够将很多场景下的习惯转为自动配置,让开发者将精力放在业务代码上。例如,添加了spring-boot-starter-web依赖,会自动添加Tomcat和Spring MVC的依赖,Spring Boot会对Tomcat和Spring MVC进行自动配置:
EnableAutoConfiguration也是一个组合注解:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
其中最关键的是@Import(EnableAutoConfigurationImportSelector.class),它的作用是:
将所有符合条件的Configuration配置类都自动加载到当前的Spring IoC容器中
而实现这一自动加载借助了Spring框架自带的一个工具类SpringFactoriedLoader
下一小节将探究springboot的自动加载具体如何实现的。