说明

在springboot项目启动时,componentScan会扫描项目根路径下所有的组件并且加载到spring容器中。但对于外部引入的maven依赖,由于jar包的位置不自在根目录,组件扫描是不起作用的。如果我们项目中需要引入一个自己开发的模块,该如何让springboot自动识别并加载到容器中呢? 今天我们参考官方讲述下spring自动装配组件的用法。

这里是指springboot自动装配的一个很重要部分,但并不是自动装配完整过程。

过程

定位需要装配的类

spring-boot启动的时候会找到starter jar包中的resources/META-INF/spring.factories文件,根据spring.factories文件中的配置,找到EnableAutoConfiguration的value指定的类,这些就是需要自动配置的标注了类。

  1. 开启自动装配得类,不要同时开启componentScan扫描。
  2. 如果想引入个别包之外的个别类,推荐使用@import注解
  3. 可以使用@AutoConfigureBefore @AutoConfigureAfter @AutoConfigureOrder控制配置类的加载顺序

条件注解说明

sprignboot提供了一些列的注解用来避免自动装配冲突,即在xxx条件满足时执行自动装配,否则不执行,这些注解名字通俗易懂,例如

  • @conditionalOn[Missing]Class,标注在@confguration配置类上,指定类是否存在决定是否加载配置
  • @conditionalOn[Missing]Bean,标注在@Bean
  • @ConditionalOnProperty 配置满足条件时
  • @ConditionalOnResource 检查resource是否存在
  • @ConditionalOnWebApplication 在当前工程是web工程时
  • @ConditionalOnExpression SpEL表达式满足时

注:上面条件都是starter被引入的功能成中判断的

maven依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

spring-boot-configuration-processor的作用:spring会通过注解处理器整理所有自动装配信息到META-INF/spring-autoconfigure-metadata.properties中,可以加速自动装配的过程。不影响理解自动装配,可以参考官方文档说明。

https://docs.spring.io/spring-boot/docs/2.1.15.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-additional-metadata

加载配置文件

我们通过@ConfigurationProperties +@Component注解可以加载配置文件到实例中,但starter不在根路径,所以@ConfigurationProperties是不起作用的。需要用到@EnableConfigurationProperties使其生效

@ConfigurationProperties(prefix = "hello")
public class HelloServiceProperties {
    private String name ;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

编译器会报错提示你必须使用@EnableConfigurationProperties注册属性配置

@EnableConfigurationProperties(HelloServiceProperties.class)
@Configuration
public class HelloAutoConfiguration {

    @Autowired
    HelloServiceProperties properties;

    @Bean
    HelloService helloService(){
        System.out.println("自动装配属性"+properties.getName());
        return new HelloService();
    }

}

自动装配类

resources->META-INF-spring.factories文件中添加自动装配类,springboot会自动扫描并处理HelloAutoConfiguration配置类

# 将HelloWorldAutoConfiguration类指定为自动装配的对象
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kouryoushine.autoconfigdemo.HelloAutoConfiguration,\
com.kouryoushine.autoconfigdemo.AspectLogAutoConfiguration

后记

以上可以了spring的基础配置,简单来说就是spring提供了一种spring.factories文件的方式。你把你需要装配的类放进去,spring就会找到并且加载到容器中。配合starter使用可以使模块化更加清晰。