自动装配原理

自动装配 - 图1
image.png

在我们配置文件中能配置的东西,都存在一个固有的规律: xxxAutoConfiguration: 默认值 xxxProperties和配置文件绑定,我们就可以使用自定义的配置了!
导入一个东西,在项目中搜索xxxProperties,看它的配置,比如ThymeleafProperties
我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

  • Positive matches:@Conditional条件为真,配置类被Spring容器加载。
  • Negative matches: @Conditional条件为假,配置类未被Spring容器加载。
  • Exclusions: 应用端明确排除加载配置
  • Unconditional classes: 自动配置类不包含任何类级别的条件,也就是说,类始终会被自动加载。

一句话总结 :根据当前不同的条件判断(Spring的@Conditional派生注解),决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类

image.png

@ComponentScan和@Import

@ComponentScan会扫描basePackages包内的component,如果不配置basePackages,默认扫描当前包(AnimalScanConfiguration)内的component.

Finally, any new bean added to the animal package will be automatically found by our context. And we still have explicit control over the configurations we are using. @Import is very similar to @ComponentScan, except for the fact that @Import has an explicit approach while @ComponentScan uses an implicit one.

  1. package com.baeldung.importannotation.animal;
  2. // imports...
  3. @Configuration
  4. @ComponentScan(basePackages = "com.baeldung.importannotation.animal")
  5. public class AnimalScanConfiguration {
  6. }
  1. package com.baeldung.importannotation.zoo;
  2. // imports...
  3. @Configuration
  4. @Import(AnimalScanConfiguration.class)
  5. class ZooApplication {
  6. }

@EnableAutoConfiguration

Exclude Auto Configuration

自动配置顺序

使用@AutoConfigureBefore调整配置顺序竟没生效?

正确姿势只需要下面两步:

  1. 把需要自动配置的类挪动到Application扫描不到的包内 (应用的@ComponentSan扫描不到的)
  2. 当前工程里增加配置META-INF/spring.factories,前后顺序对结果无影响:
  • 若你不用@AutoConfigureBefore这个注解,单单就想依赖于spring.factories里的先后顺序的来控制实际的加载顺序,答案是不可以,控制不了
  • Spring Boot的自动配置均是通过spring.factories来指定的,它的优先级最低(执行时机是最晚的);通过扫描进来的一般都是你自己自定义的配置类,所以优先级是最高的,肯定在自动配置之前加载
    • 从这你应该学到:若你要指定扫描的包名,请千万不要扫描到形如org.springframework这种包名,否则“天下大乱”(当然喽为了防止这种情况出现,Spring Boot做了容错的。它有一个类专门检测这个case防止你配置错了,具体参见ComponentScanPackageCheck默认实现(规避了org.springframework))
  • 请尽量不要让自动配置类既被扫描到了,又放在spring.factories配置了,否则后者会覆盖前者,很容易造成莫名其妙的错误

小总结,对于三大注解的正确使用姿势是应该是:请使用在你的自动配置里(一般是你自定义starter时使用),而不是使用在你业务工程中的@Configuration里,因为那会毫无效果。

SpringApplication.run

了解
image.png
不止运行一个main方法,且开启了一个服务。不像tomcat容器运行,而是进程运行。

  • 实例化
  • run()
  • 监听器
  • bean

    @ConfigurationProperties和@Value的对比

  • 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

  • 如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
    • @PropertySource :加载指定的配置文件;(也还是要用@Value SPEL表达式);
    • @configurationProperties:默认从全局配置文件中获取值;最大用处是给配置类赋值(对应的是实体类)

image.png

  • 松散绑定: last-name —— lastName
  • SpEL表达式:”${xxx}”
  • 复杂类型封装,yml中可以封装对象 , 使用value就不支持

JSR303校验

spring-boot-starter-validation 集成了hibernate-validate

  • @Validated
  • @Email
  • spring-boot-configuration-processor

    3.1. Configuring the Annotation Processor

    You can easily generate your own configuration metadata file from items annotated with @ConfigurationProperties by using the spring-boot-configuration-processor jar. The jar includes a Java annotation processor which is invoked as your project is compiled. With Maven the dependency should be declared as optional, as shown in the following example:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-configuration-processor</artifactId>
  4. <optional>true</optional>
  5. </dependency>

If you have defined @ConfigurationProperties in your application, make sure to configure the spring-boot-maven-plugin to prevent the repackage goal from adding the dependency into the fat jar:

  1. <project>
  2. <build>
  3. <plugins>
  4. <plugin>
  5. <groupId>org.springframework.boot</groupId>
  6. <artifactId>spring-boot-maven-plugin</artifactId>
  7. <configuration>
  8. <excludes>
  9. <exclude>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-configuration-processor</artifactId>
  12. </exclude>
  13. </excludes>
  14. </configuration>
  15. </plugin>
  16. </plugins>
  17. </build>
  18. </project>