1.@SpringBootApplication注解
springboot是基于spring的新型的轻量级框架,最厉害的地方当属自动配置
@SpringBootApplication//标注在某个类上,表示这个类是SpringBoot的启动类
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication.run)最为耀眼,所以要揭开SpringBoot的神秘面纱,我们要从这两位开始就可以了。
进入@SpringBootApplication注解,包含以下注解
@SpringBootConfiguration//表示当前类是一个IoC容器的配置类
@EnableAutoConfiguration //开启SpringBoot自动装配功能
@ComponentScan(excludeFilters = {// 扫描路径设置
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes =AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
2、SpringBootConfiguration注解
包括了@Configuration,配合@Bean代替xml配置文件的形式注入bean
a)xml配置文件的形式注入bean
<bean id="mockService" class="..MockServiceImpl">
...
</bean>
b)注解配置形式注入bean
@Configuration
public class MockConfiguration{
/*
*任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该
*bean定义的id。
*/
@Bean
public MockService mockService(){
return new MockServiceImpl();
}
}
3、@EnableAutoConfiguration注解
@EnableAutoConfiguration:开启SpringBoot自动装配功能,在默认的情况下就是将:主配置类(@SpringBootApplication
)的所在包及其子包里边的组件扫描到Spring容器中。(看完这句话,会不会觉得,这不就是ComponentScan的功能吗?这俩不就重复了吗?比如说,你用了Spring Data JPA,可能会在实体类上写@Entity
注解。这个@Entity
注解由@AutoConfigurationPackage
扫描并加载,而我们平时开发用的@Controller/@Service/@Component/@Repository
这些注解是由ComponentScan
来扫描并加载的。)
@AutoConfigurationPackage// 自动配置包controller、service----->IOC容器
@Import(EnableAutoConfigurationImportSelector.class)//自动配置
public @interface EnableAutoConfiguration {
...
}
3.1@AutoConfigurationPackage注解
AutoConfigurationPackages.Registrar.class将启动类(@SpringBootApplication标注的类)的所在包及子包里面所有组件扫描到Spring容器;
AutoConfigurationImportSelector:自动配置导入选择器,给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
3.2@Import注解
@Import自动注册包和@ComponentScan自动扫描包,是联动的,Spring底层注解@import,给容器中导入一个组件。回到@Import(AutoConfigurationImportSelector.class)
这句代码上,再点进去AutoConfigurationImportSelector.class
看看具体的实现是什么
我们再进去看一下这些配置信息是从哪里来的(进去getCandidateConfigurations方法):
这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载,还没看到关键信息,继续进去:
FACTORIES_RESOURCE_LOCATION
的值是META-INF/spring.factories
- Spring启动的时候会扫描所有jar路径下的
META-INF/spring.factories
,将其文件包装成Properties对象 - 从Properties对象获取到key值为
EnableAutoConfiguration
的数据,然后添加到容器里边。
@Import(AutoConfigurationImportSelector.class):其中AutoConfigurationImportSelector类中有一个getCandidateConfigurations()方法,该方法通过SpringFactoriesLoader.loadFactoryNames()方法查找位于META-INF/spring.factories文件中的所有自动配置类,并加载这些类。
spring.factories文件是以key-value键值对的形式存储文件里,其中有一个key=EnableAutoConfiguration,它对应的value值就是一个个以AutoConfiguration结尾来命名的 xxxAutoConfiguration 自动配置类。
4.@ComponentScan
作用:自动扫描包(扫描当前主启动类同级的包)并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。
我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从@ComponentScan所在类的package进行扫描。
5.最后会默认加载113个默认的配置类
文件及配置类
六、总结
Spring Boot 自动化配置也是基于 Spring Factories 机制实现的,在 spring-boot-autoconfigure-xxx.jar 类路径下的 META-INF/spring.factories 中设置了 Spring Boot 自动配置的内容
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
......
以上配置中,value 取值是由多个 xxxAutoConfiguration (使用逗号分隔)组成,每个 xxxAutoConfiguration 都是一个自动配置类。Spring Boot 启动时,会利用 Spring-Factories 机制,将这些 xxxAutoConfiguration 实例化并作为组件加入到容器中,以实现 Spring Boot 的自动配置。
七、 步骤
SpringBoot启动的时候加载主配置类,@EnableAutoConfiguration注解开启了自动配置功能。
@EnableAutoConfiguration 作用 (getAutoConfigurationEntry-->getCandidateConfigurations)
扫描所有jar包类路径下 META-INF/spring.factories把扫描到的这些文件的内容包装成properties对象从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用他们来做自动配置。
3.对每一个自动配置类进行自动配置功能。
4.根据当前不同的条件判断,决定这个配置类是否生效。一但这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的。
5.所有在配置文件中能配置的属性都是在xxxxProperties类中封装者,配置文件能配置什么就可以参照某个功能对应的这个属性类。
总结:
SpringBoot启动会加载大量的自动配置类
先看我们需要的功能有没有SpringBoot默认写好的自动配置类
再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件有,我们就不需要再来配置了)
给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值
xxxxAutoConfigurartion:自动配置类;给容器中添加组件;
xxxxProperties:封装配置文件中相关属性;