我们知道spring是简化java开发,在做一个大型的网站开发时,我们可以整合ssm来实现,但在整合过程中还是会做各种复杂的配置,因此spring boot便应运而生,其目的时简化spring开发,我们通过启动类一层一层的探究springboot自动配置,通过对源码的分析可以让我们更加了解spring boot的开发使用
简单的spring boot程序启动类
我们可以发现,除了 @SpringBootApplication ,我们的项目没有其他的配置或注解,我们进入这个注解
启动类注解作用
1.@SpringBootConfiguration
@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 {
@SpringBootConfiguration:Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类;
进入这个注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration:配置类上来标注这个注解,表示这是一个配置类,作用和配置文件一样,配置类也是容器中的组件
2.@EnableAutoConfiguration
开启自动配置功能,在之前做web项目的时候,需要配置有关mvc的内容,比如配置前端控制器等,在这里都没有配置,原因就是 @EnableAutoConfiguration 帮我们进行自动配置了,我们进入这个注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration
我们只关注以下内容:
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration
- 2.1 @AutoConfigurationPackage:自动配置包,我们进入这个注解:
@Import({Registrar.class})
public @interface AutoConfigurationPackage
@Import是spring底层注解,给容器导入组件,在这里是导入Registrar.class
这个组件,我们进入这个类
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
}
}
在这个类中registerBeanDefinitions
方法,注册一些bean定义信息,我们可以看出这个方法是根据注解的元信息返回包名,我们打断点来观察这个方法:
在得到元信息之后,我们计算
(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()
这个字段:
我们可以发现,这个字段返回了我们的包名:com.rwh
,对比我们的spring以及我们上面的分析,我们有一种似曾相识的感觉,在spring中,被@ComponentScan
标记的类都会自动扫描该类的的包以及该类的子包,在这里,我们的启动类在com,rwh
包中,从上面返回的包名我们可以得出结论:
@AutoConfigurationPackage将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器
- 2.2@Import({EnableAutoConfigurationImportSelector.class})
这个注解也是我们了解@EnableAutoConfiguration
的第二个注解,我们知道@Import
是给容器中添加组件,这里是导入EnableAutoConfigurationImportSelector.class
进入这个注解,查看它的父类:
通过这个方法 SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;
如图所示:
这样springboot就帮我们自动导入了我们开发时所需要的各种组件