SpringBoot相比Spring的优点
1.开发基于 Spring 的应⽤程序很容易。
2.Spring Boot 项⽬所需的开发或⼯程时间明显减少,通常会提⾼整体⽣产⼒。
3.Spring Boot 不需要编写⼤量样板代码、XML 配置和注释。 4.Spring 引导应⽤程序可以很容易地与 Spring ⽣态系统集成,如 Spring JDBC、Spring ORM、Spring Data、Spring Security 等。 5.Spring Boot 遵循“固执⼰⻅的默认配置”,以减少开发⼯作(默认配置可以修改)。
6.Spring Boot 应⽤程序提供嵌⼊式 HTTP 服务器,如 Tomcat 和 Jetty,可以 轻松地开发和测试 web 应⽤程序。(这点很赞!普通运⾏ Java 程序的⽅式 就能运⾏基于 Spring Boot web 项⽬,省事很多)
7.Spring Boot 提供命令⾏接⼝(CLI)⼯具,⽤于开发和测试 Spring Boot 应⽤ 程序,如 Java 或 Groovy。
8.Spring Boot 提供了多种插件,可以使⽤内置⼯具(如 Maven 和 Gradle)开发 和测试 Spring Boot 应⽤程序。
自动装配原理
这个是因为@SpringBootApplication注解的原因。@SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
@EnableAutoConfiguration:启⽤ SpringBoot 的⾃动配置机制 @ComponentScan: 扫描被@Component ( @Service , @Controller )注解的 bean,注解默认会扫描该类所在的包下所有的类。
@Configuration:允许在上下⽂中注册额外的 bean 或导⼊其他配置类
最重要的注解@EnableAutoConfiguration 开启自动装配类
重要注解!
1.@AutoConfigurationPackage
@AutoConfigurationPackage和@ComponentScan一样,也是将主配置类所在的包及其子包里面的组件扫描到IOC容器中,但是区别是
- @AutoConfigurationPackage扫描@Enitity、@MapperScan等第三方依赖的注解
- @ComponentScan只扫描@Controller/@Service/@Component/@Repository这些常见注解。所以这两个注解扫描的对象是不一样的。
2.核心注解Import(AutoConfigurationImportSelector.class)
-
- 作用:通过import导入第三方提供的bean的配置类:AutoConfigurationImportSelector:给容器中导入组件
- 该类中有selectImports()方法,调用了getAutoConfigurationEntry()
其下又调用了getCandidateConfigurations()
getCandidateConfigurations()中SpringFactoriesLoader.loadFactoryNames()方法
SpringFactoriesLoader.loadFactoryNames()中传入参数EnableAutoConfiguration.class - 作用:扫描所有jar包类路径下的META-INF/spring.factories文件,将扫描到的这些文件包装成properties对象,从properties中获取到EnableAutoConfiguration.class类名对应的值,将这些值添加到容器中,用这些类做自动配置功能
-
在spring-boot-autoconfigure-.jar包中找到spring.factories文件
其中spring.factories文件是一组组的key=value的形式
-
- key=接口 value=接口实现类(多个,逗号隔开)
以HttpEncodingAutoConfiguration为例解释:
- key=接口 value=接口实现类(多个,逗号隔开)
@Configuration(proxyBeanMethods = false)————表示该类为配置类
@EnableConfigurationProperties(ServerProperties.class)————将配置文件中设置的值与properties中的属性绑定,将组件添加到IOC容器
————@Conditionalxxx:若满足不同的条件,则配置类中的配置生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = “server.servlet.encoding”, value = “enabled”, matchIfMissing = true)
其中ServerProperties.class中的属性值,可与xx.yaml配置文件绑定并修改
这个properties文件存放了配置文件
精髓:根据当前配置类的条件判断配置类是否生效,若生效,则添加各种组件,会从properties类中获取属性,可以在配置文件xxx.yaml中设置属性的值
- Properties类:封装配置文件的相关属性。
- AutoConfiguration类:自动配置类,添加到IOC容器中。
SpringFactoriesLoader
- 作用:从classpath/META-INF/spring.factories文件中,根据key来加载对应的类到spring IOC容器中。
自动装配过程
- 通过各种注解实现了类与类之间的依赖关系,容器在启动的时候SpringApplication.run(),调用EnableAutoConfigurationImportSelector.class的selectImports方法
- selectImports方法调用SpringFactoriesLoader.loadFactoryNames方法扫描jar包类路径下的META-INF/spring.factories文件下,获取BeanConfiguration列表
- loadFactoryNames方法会读取spring.factories中EnableAutoConfiguration.class类名对应的值
- 根据这些类上的注解判断,若条件满足,则该配置类生效,将配置文件中自己设置的属性值配置到对应的配置类中,最后注入到IOC容器中实现自动配置
SpringBoot条件注解
- @ConditionalOnBean:当容器里有指定 Bean 的条件下
- @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
- @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
- @ConditionalOnClass:当类路径下有指定类的条件下
- @ConditionalOnMissingClass:当类路径下没有指定类的条件下
- @ConditionalOnProperty:指定的属性是否有指定的值
- @ConditionalOnResource:类路径是否有指定的值
- @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
- @ConditionalOnJava:基于 Java 版本作为判断条件
- @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
- @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
- @ConditionalOnWebApplication:当前项目是 Web 项 目的条件下
配置文件加载顺序
(Bootstrap最先)
- 1、file:./config/*/application.properties
- 2、file:./config/*/application.yml
- 3、file:./config/application.properties
- 4、file:./config/application.yml
- 5、file:./application.properties
- 6、file:./application.yml
- 7、classpath:/config/application.properties
- 8、classpath:/config/application.yml
- 9、classpath:/application.properties
- 10、classpath:/application.yml
自定义Starter
Spring Boot Starter是一种简化Spring Boot应用开发的机制,它可以通过引入一些预定义的依赖和配置,让我们快速地集成某些功能模块,而无需繁琐地编写代码和配置文件。Spring Boot官方提供了很多常用的Starter,例如spring-boot-starter-web、spring-boot-starter-data-jpa等,但有时候我们也需要根据自己的业务需求,创建一些自定义的Starter,以便在不同的项目中复用一些通用的功能或组件。
一、Starter的命名规范
在创建一个自定义的Starter之前,我们需要先确定它的名称。Starter的命名有一种习惯,官方的Starter一般都是以spring-boot-starter-为前缀,后面跟上模块名,例如spring-boot-starter-web表示集成了Web开发相关的依赖和配置。而我们自定义的Starter一般都是以模块名为前缀,后面跟上-spring-boot-starter。这样做的目的是为了避免与官方或其他第三方提供的Starter产生冲突或混淆。
二、Starter项目的结构
创建一个自定义的Starter项目和创建一个普通的Spring Boot项目没有太大区别,我们可以使用IDE或者Spring Initializr来快速生成一个基本的项目结构。一个典型的Starter项目
woniu-spring-boot-starter
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com.woniu.util
│ │ │ ├── autoconfigure // 自动配置类所在的包
│ │ │ │ ├── AutoConfiguration.java // 自动配置类
│ │ │ │ └── Properties.java // 属性类
│ │ │ └── util // 业务功能类所在的包
│ │ │ └── Util.java // 业务功能类
│ │ └── resources
│ │ └── META-INF
│ │ └── spring.factories // Spring Boot自动装配文件
│ └── test
│ └── java
├── pom.xml // Maven依赖管理文件
└── README.md // 项目说明文档
三、Starter项目的依赖
在创建一个自定义的Starter项目时,我们需要在pom.xml文件中添加一些必要的依赖。首先,我们需要添加spring-boot-starter作为基础依赖,它提供了Spring Boot核心功能和默认配置。其次,我们需要添加spring-boot-configuration-processor作为编译时依赖,它可以帮助我们生成属性类和配置元数据,并且设置为可选依赖,避免传递给其他项目。最后,我们需要添加我们要集成的功能模块相关的依赖。
<dependencies>
<!-- 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 编译时依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
四、Starter项目的属性类
在创建一个自定义的Starter项目时,我们需要编写一个属性类,用来定义我们要集成的功能模块所需的配置项,并且使用@ConfigurationProperties注解来指定配置文件中的前缀。
五、Starter项目的业务功能类
在创建一个自定义的Starter项目时,我们需要编写一个或多个业务功能类,用来实现我们要集成的功能模块的具体逻辑。
六、Starter项目的自动配置类
在创建一个自定义的Starter项目时,我们需要编写一个自动配置类,用来根据属性类和业务功能类,创建相应的Bean对象,并且使用@EnableConfigurationProperties注解来启用属性类,使用@ConditionalOnClass注解来判断业务功能类是否存在,使用@ConditionalOnProperty注解来判断配置文件中是否有相应的配置项。
七、Starter项目的自动装配文件
在创建一个自定义的Starter项目时,我们需要在resources/META-INF目录下创建一个名为spring.factories的文件,用来指定我们的自动配置类,让Spring Boot能够在启动时自动扫描并加载它。以下是一个示例:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.woniu.util.autoconfigure.SwaggerConfiguration
八、Starter项目的使用方法
在完成了一个自定义的Starter项目后,我们可以将它打包成jar文件,并且发布到Maven仓库或者本地仓库,这样就可以在其他项目中引用它了。例如,在本例中,我们可以在其他项目的pom.xml文件中添加如下依赖:
<dependency>
<groupId>com.swagger</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
然后,在其他项目的配置文件中添加如下配置项:
swagger:
enable: true
enableResponseWrap: true
最后,在其他项目的代码中,我们可以通过注入Swagger类来调用API接口文档功能。
九、Starter项目的原理
Starter项目的核心原理是基于Spring Boot的自动装配机制,即根据类路径和配置文件中的条件,动态地创建和注入Bean对象到应用上下文中。Starter项目通过在resources/META-INF目录下创建一个名为spring.factories的文件,来指定自动配置类的全限定名,让Spring Boot在启动时能够扫描并加载它。自动配置类则通过一系列的注解来定义和控制自动装配的逻辑,例如:
- @Configuration注解标识这是一个配置类,用来创建和注册Bean对象。
- @EnableConfigurationProperties注解启用属性类,并将其注入到配置类中。
- @ConditionalOnClass注解判断类路径中是否存在指定的类,如果存在则满足条件。
- @ConditionalOnProperty注解判断配置文件中是否存在指定的属性,如果存在并且值与期望相符,则满足条件。
- @Bean注解根据属性类和业务功能类,创建相应类型的Bean对象,并注册到应用上下文中。
当所有的条件都满足时,Starter项目就能实现自动装配的功能,让我们无需手动编写和配置Bean对象,只需引入依赖和设置属性即可。