Spring Boot 基本上是 Spring 框架的扩展,它消除了设置 Spring 应用程序所需的复杂例行配置。我们在使用 Spring 框架的时候,我们接触得比较多的应该是 Spring MVC、 IOC 、 DI 、AOP 等等,而这些框架在使用的过程中会需要配置大量的 XML,或者需要做很多繁琐的配置。Spring Boot 可以帮助我们快速搭建一个基于 Spirng 框架以及 Spring 生态体系的应用解决方案。
@SpringBootApplication实际上是一个复合注解,主要由以下构成:
@Configuration
@Configuration是 JavaConfig 形式的基于 Spring IOC 容器的配置类使用的一种注解。所以在启动类里面标注了 @Configuration,意味着它其实也是一个 IoC 容器的配置类。
传统意义上的 Spring 应用都是基于 xml 形式来配置 bean 的依赖关系。但是从 Spring3 开始,Spring 就支持了两种 bean 的配置方式,一种是基于 xml 文件方式,另一种就是 JavaConfig,任何一个标注了 @Configuration 的 Java 类定义都是一个 JavaConfig 配置类。而在这个配置类中,任何标注了 @Bean 的方法,它的返回值都会作为 Bean 定义注册到 Spring 的 IoC 容器,方法名默认成为这个 Bean 的 id。然后通过 spring 容器在启动的时候,把 Bean 进行初始化并且,如果 Bean 之间存在依赖关系,则分析这些已经在 IoC 容器中的 Bean 根据依赖关系进行组装。
@ComponentScan
@ComponentScan 就是扫包,相当于 xml 配置文件中的context:component-scan 。
它的主要作用就是扫描指定路径下的标识了需要装配的类,自 动装配到 Spring 的 IoC 容器中。
标识需要装配的类的形式主要是:@Component、@Repository、@Service、@Controller 这类的注解标识的类。(注:@Repository、@Service、@Controller 的底层还是 @Component)。ComponentScan 默认会扫描当前 package 下的的所有加了相关注解标识的类到 IoC 容器中。
@EnableAutoConfiguration
@EnableAutoConfiguration 是 Spring Boot 的灵魂。从 Spring3.1 开始,提供了一系列的 @Enable 开头的注解,它是在 JavaConfig 框架上更进一步的完善,使用户在使用 Spring 相关的框架避免配置大量的代码从而降低使用的难度。
每一个涉及到 Enable 开头的注解,都会带有一个 @Import 的注解, @EnableAutoConfiguration 也不例外。
@Import 对应 XML 形式下的
普通 Bean 或者带有 @Configuration 的配置文件
实现 ImportSelector 接口进行动态注入
实现 ImportBeanDefinitionRegistrar 接口进行动态注入
这里导入的是第二种 importSelector,这是一种动态注入 Bean 的技术。其中AutoConfigurationImportSelector实现了 ImportSelector 接口。借助AutoConfigurationImportSelector
,@EnableAutoConfiguration
帮助SpringBoot应用将所有符合条件的@Configuration
配置都加载到当前SpringBoot创建并使用的IoC容器。
在AutoConfigurationImportSelector类中可以看到通过 SpringFactoriesLoader.loadFactoryNames()
把 spring-boot-autoconfigure.jar/META-INF/spring.factories中每一个xxxAutoConfiguration文件都加载到容器中,spring.factories文件里每一个xxxAutoConfiguration文件一般都会有下面的条件注解:
SpringFactoriesLoader属于Spring框架私有的一种扩展方案(类似于Java的SPI方案java.util.ServiceLoader),其主要功能就是从指定的配置文件META-INF/spring-factories
加载配置,spring-factories是一个典型的java properties文件,只不过Key和Value都是Java类型的完整类名。
对于@EnableAutoConfiguration
来说,SpringFactoriesLoader的用途稍微不同一些,其本意是为了提供SPI扩展的场景,而在@EnableAutoConfiguration
场景中,它更多提供了一种配置查找的功能支持,即根据@EnableAutoConfiguration
的完整类名org.springframework.boot.autoconfig.EnableAutoConfiguration
作为查找的Key,获得对应的一组@Configuration
类。
SpringFactoriesLoader是一个抽象类,类中定义的静态属性定义了其加载资源的路径public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"
,此外还有三个静态方法:
loadFactories方法首先获取类加载器,然后调用loadFactoryNames
方法获取所有的指定资源的名称集合、接着调用instantiateFactory
方法实例化这些资源类并将其添加到result集合中。最后调用AnnotationAwareOrderComparator.sort
方法进行集合的排序。
SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。
starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。
org.springframework.boot
spring-boot-autoconfigure
org.springframework.boot
spring-boot-maven-plugin
spring-boot-autoconfigure
中包含大量核心注解,包含条件注解等。
@ConfigurationProperties(prefix = "com.test")
public class TestServiceProperties {
private String name = "test";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@ConfigurationProperties
配置此注解可以自动导入application.properties配置文件中的属性,前提需要指定属性前缀prefix。如果application.properties文件中未指定相应属性,便使用默认的,如上name="test"。
public class TestServiceConfiguration {
private String name;
public String getName() {
return "name is " + name;
}
public void setName(String name) {
this.name = name;
}
}
@Configuration
@EnableConfigurationProperties(TestServiceProperties.class)
@ConditionalOnClass(TestServiceConfiguration.class)
@ConditionalOnProperty(prefix = "com.test", value = "enabled", matchIfMissing = true)
public class TestServiceAutoConfiguration {
@Autowired
private TestServiceProperties testServiceProperties;
@Bean
@ConditionalOnMissingBean(TestServiceConfiguration.class)
public TestServiceConfiguration testServiceConfiguration() {
TestServiceConfiguration testService = new TestServiceConfiguration();
TestService.setName(testServiceProperties.getName());
return testService;
}
}
@Configuration
:表明此类是一个配置类,将变为一个bean被spring进行管理。@EnableConfigurationProperties
:启用属性配置,将读取TestServiceProperties里面的属性。@ConditionalOnClass
:当类路径下面有TestServiceConfiguration此类时,自动配置。@ConditionalOnProperty
:判断指定的属性是否具备指定的值。@ConditionalOnMissingBean
:当容器中没有指定bean时,创建此bean。在resources文件夹下面新建一个META-INF文件,并在下面创建spring.factories文件,将配置类进行注册。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.test.TestServiceAutoConfiguration
自定义的starter
编写完毕,执行mvn clean install
将项目打成一个jar包。新建一个springboot项目,在pom文件中添加刚刚打包的jar。
在application.properties添加
com.test.name=test