Πέμπτη 21 Οκτωβρίου 2021

Spring Certification: Spring Boot Auto Configuration

How does Spring Boot know what to configure?
  • These classes contain ConditionalOn.. classes that scan classpath resources and register beans, according to starters and dependencies that user introduced in POMs
  • Spring Boot checks for the presence of a META-INF/spring.factories file within your published jar. The file should list your configuration classes under the EnableAutoConfiguration key, as shown in the following example:
    • org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.code.in.packets.autoconf.SomeAutoConfiguration1,\
      com.code.in.packets.autoconf.SomeAutoConfiguration2
  • See all ConditionalOn classes
  • Using @Profile("some-profile") on a @Bean, and then load this profile

  • Using @Conditional("<some-class>") on a @Bean




What does @EnableAutoConfiguration do?

  • Applied in Application/Main class of Spring application
  • In Spring Boot application, already included in @SpringBootApplication annotation
  • Responsible for kick-starting autoconfiguration process, by
    • @AutoConfigurationPackage
      • Importing AutoConfigurationPackages.Registrar, that registers a bean which provides Bean list for Spring boot to use internally, in spring-boot-autoconfigure package
    • @Import(EnableAutoConfigurationImportSelector.class)
      • Imports AutoConfigurationImportSelector that aggregates all spring.factories
  • Can exclude some autoconfiguration class, like: @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) in our @Configuration class



What does @SpringBootApplication do?

  • Applied only in root package class, and contains below annotations:
  • @EnableAutoConfiguration: enables Spring Boot’s auto-configuration mechanism
  • @ComponentScan: enable @Component scan on the package where the application is located
  • @Configuration: allow to register extra beans in the context or import additional configuration classes

Does Spring Boot do component scanning? Where does it look by default?
  • Yes, @ComponentScan or @SpringBootApplication enables component scanning.
  • By default, it scans for components in whole package (and subpackages) of the class with @SpringBootApplication
  • If no component scanning is set, it only scans the package of the main class
  • @ComponentScan is also used to specify base packages and base package classes using thebasePackageClasses or basePackages attributes


How are DataSource and JdbcTemplate auto-configured?
  • DataSource 
    •  with DataSourceAutoConfiguration class from spring-boot-autoconfigure package.
    • that retrieves properties spring.datasource.url, spring.datasource.username, spring.datasource.password from application.properties or yml file.
  • JdbcTemplate
    • with JdbcTemplateAutoConfiguration, that contains:
    • @ConditionalOnClass(value={javax.sql.DataSource.class,org.springframework.jdbc.core.JdbcTemplate.class})
      • If DataSource class exists in classpath, only then configure JdbcTemplate
    • @ConditionalOnSingleCandidate(value=javax.sql.DataSource.class)
      • We need only one candidate
    • @AutoConfigureAfter(value=DataSourceAutoConfiguration.class) 
      • First configure DataSource, and only then JdbcTemplate 

What is spring.factories file for?
  • spring.factories contains auto-configuration classes needed for the AutoConfiguration mechanism of Spring
  • @EnableAutoConfiguration eventually gathers all spring.factories files of all project modules/packages and aggregates them into one.
  • A spring.factories contains an EnableAutoConfiguration key with values as the list of auto-configuration classes, and resides under META/INF directory
  • spring.factories should be used when we want to set default components globally for our app. Thus the need for @Autowire-ing a dependency disappears. But of course, this default behavior can later be overwritten with some @Bean/@Configuration


How do you customize Spring Boot auto configuration?
  • To create our own auto-configuration: 
    • add a spring.factories in META-INF, with content:
    • org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.myapp.package1.autoconfigure.MyDataSourceAutoConfiguration, com.myapp.package2.autoconfigure.MyJpaAutoConfiguration
    • Implement above classes as @Configurations accordingly to specific needs
    • Disable loading of auto-configuration class for DataSource loading:  @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) 


What are the examples of @Conditional annotations? How are they used?

Conditional classes are used from within AutoConfiguration classes to load conditionally classpath resources :
  • ConditionalOnBean - Spring Bean must be registered
  • ConditionalOnMissingBean - Spring Bean must not be registered
  • ConditionalOnClass - Class must exist in classpath
  • ConditionalOnMissingClass - Class must not exist in classpath
  • ConditionalOnExpression - spEL expression must result to true
  • ConditionalOnJava - Java JDK in certain version must exist
  • ConditionalOnJndi - JNDI location should exist
  • ConditionalOnProperty - property must exist
  • ConditionalOnResource - resource must exist

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

What may be missing, or could get better?