Spring boot 官网学习笔记 - Auto-configuration(@SpringBootApplication、@EnableAutoConfiguration、@Configuration)

时间:2022-09-24 12:46:11
  1. Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, if HSQLDB is on your classpath, and you have not manually configured any database connection beans, then Spring Boot auto-configures an in-memory database.

    You need to opt-in to auto-configuration by adding the @EnableAutoConfiguration or @SpringBootApplication annotations to one of your @Configuration classes.

    Spring boot 官网学习笔记 - Auto-configuration(@SpringBootApplication、@EnableAutoConfiguration、@Configuration) Tip

    You should only ever add one @SpringBootApplication or @EnableAutoConfiguration annotation. We generally recommend that you add one or the other to your primary @Configuration class only.

  2. 16.1 Gradually(逐步) Replacing Auto-configuration

    Auto-configuration is non-invasive(非侵害的). At any point, you can start to define your own configuration to replace specific parts of the auto-configuration. For example, if you add your own DataSource bean, the default embedded database support backs away.

    If you need to find out what auto-configuration is currently being applied, and why, start your application with the --debug switch. Doing so enables debug logs for a selection of core loggers and logs a conditions report to the console.

    16.2 Disabling Specific Auto-configuration Classes

    If you find that specific auto-configuration classes that you do not want are being applied, you can use the exclude attribute of @EnableAutoConfiguration to disable them, as shown in the following example:

    import org.springframework.boot.autoconfigure.*;
    import org.springframework.boot.autoconfigure.jdbc.*;
    import org.springframework.context.annotation.*; @Configuration
    @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
    public class MyConfiguration {
    }

    If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead. Finally, you can also control the list of auto-configuration classes to exclude by using the spring.autoconfigure.exclude property.

    Spring boot 官网学习笔记 - Auto-configuration(@SpringBootApplication、@EnableAutoConfiguration、@Configuration) Tip

    You can define exclusions both at the annotation level and by using the property.

  3. @SpringBootApplication
    1. @SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
  4. @EnableAutoConfiguration
    1. 把 spring-boot-autoconfigure.jar/META-INF/spring.factories中每一个xxxAutoConfiguration文件都加载到容器中,spring.factories文件里每一个xxxAutoConfiguration文件一般都会有下面的条件注解:
      
      @ConditionalOnClass : classpath中存在该类时起效
      @ConditionalOnMissingClass : classpath中不存在该类时起效
      @ConditionalOnBean : DI容器中存在该类型Bean时起效
      @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
      @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
      @ConditionalOnExpression : SpEL表达式结果为true时
      @ConditionalOnProperty : 参数设置或者值一致时起效
      @ConditionalOnResource : 指定的文件存在时起效
      @ConditionalOnJndi : 指定的JNDI存在时起效
      @ConditionalOnJava : 指定的Java版本存在时起效
      @ConditionalOnWebApplication : Web应用环境下起效
      @ConditionalOnNotWebApplication : 非Web应用环境下起效

        

  5. @ComponentScan
    1. @ComponentScan这个注解完成的是自动扫描的功能,相当于Spring XML配置文件中的:<context:component-scan>,可以使用basePackages属性指定要扫描的包,以及扫描的条件。如果不设置的话默认扫描@ComponentScan注解所在类的同级类和同级目录下的所有类,所以对于一个Spring Boot项目,一般会把入口类放在顶层目录中,这样就能够保证源码目录下的所有类都能够被扫描到。
    2. 总结一下@ComponentScan的常用方式如下

      • 自定扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入spring容器;也会扫描 @Configuration

      • 通过includeFilters加入扫描路径下没有以上注解的类加入spring容器

      • 通过excludeFilters过滤出不用加入spring容器的类

  6. @Configuration
    1. 提到@Configuration就要提到他的搭档@Bean
    2. <beans>
      <bean id = "car" class="com.test.Car">
      <property name="wheel" ref = "wheel"></property>
      </bean>
      <bean id = "wheel" class="com.test.Wheel"></bean>
      </beans> @Configuration
      public class Conf {
      @Bean
      public Car car() {
      Car car = new Car();
      car.setWheel(wheel());
      return car;
      } @Bean
      public Wheel wheel() {
      return new Wheel();
      }
      }