Home  >  Article  >  Java  >  What is the principle of java SpringBoot automatic assembly?

What is the principle of java SpringBoot automatic assembly?

王林
王林forward
2023-04-25 08:16:061103browse

summary

detail

Traditional Spring projects will have many configuration files. For example, if we want to use Redis, generally in addition to the corresponding dependent jar packages, we also need to add them to application.xml Configure JedisConnectionFactory, JedisPoolConfig, and RedisTemplate. But if you use SpringBoot, the system will automatically generate these classes based on the jar package in pom.xml and inject them into the IOC container.

Configuration is required in traditional Spring projects

<bean id="jedisConnectionFactory" class="...JedisConnectionFactory"></bean>
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"></bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"></bean>

When using SpringBoot, in addition to introducing the corresponding jar package in pom.xml, you only need to configure the corresponding property values ​​​​in application.properties

Take Redis as an example

  • Get more than 120 default function configuration classes from spring-boot-autoconfigure.jar/META-INF/spring.factories, including the functions of redis The fully qualified name of the configuration class RedisAutoConfiguration. Generally, a functional configuration class revolves around this function and is responsible for managing and creating multiple related functional classes. For example, RedisAutoConfiguration is responsible for:

JedisConnectionFactory, RedisTemplate, and StringRedisTemplate. Creation of a functional class

org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
  • One condition for the RedisAutoConfiguration configuration class to take effect is @ConditionalOnClass: JedisConnection.class, RedisOperations.class, Jedis.class, so it will go to the classpath to find the corresponding class File

@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {}
  • If pom.xml has a corresponding jar package, it can match the corresponding dependency class: JedisConnection.class, RedisOperations.class, Jedis.class

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
  • If the match is successful, this function configuration class will take effect, and the default property configuration class @EnableConfigurationProperties(RedisProperties.class)

  • will be injected.
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
    private int database = 0;
    private String url;
    private String host = "localhost";
    private String password;
    private int port = 6379;
  • The Redis function configuration will generate the final JedisConnectionFactory and RedisTemplate according to the conditions. The condition is that there are no user-defined ones in the IOC environment.

@ConditionalOnMissingBean(RedisConnectionFactory.class), RedisTemplate

@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
        @Bean
        @ConditionalOnMissingBean(RedisConnectionFactory.class)
        public JedisConnectionFactory redisConnectionFactory()
                throws UnknownHostException {
            return applyProperties(createJedisConnectionFactory());
        }

        @Bean
        @ConditionalOnMissingBean(name = "redisTemplate")
        public RedisTemplate<Object, Object> redisTemplate(
                RedisConnectionFactory redisConnectionFactory)
                        throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
}
  • The finally created default assembly class will be injected into the IOC through the @Bean annotation in the functional configuration class

Principle and result analysis

Through various annotations, SpringApplication.run(Application.class, args) will read the spring in spring-boot-autoconfigure.jar when running. Factories configuration file, the configuration file contains the className of the configuration class of all automatic assembly classes, and then generates the Configuration class corresponding to the function. If these function configuration classes are to take effect, they will go to the classpath to find whether there are dependent classes of this class (that is, pom .xml must have a jar package with corresponding functions), and then the final functional class is generated through judgment in the configuration class, and the default attribute value class is injected into the configuration class, and the functional class can be referenced and assigned a default value. The principle of generating functional classes is to give priority to customization. Automatic assembly classes will be used only when there is no customization.

To sum up, in order to automatically assemble a class, two conditions need to be met:

  • spring.factories contains a configuration class for this class (a The configuration class can create multiple dependent classes surrounding this function)

  • pom.xml needs to have the corresponding jar package

The result of the whole process is two things:

  • Based on various judgments and dependencies, the classes required by the business are finally generated and injected into the IOC container

  • The class generated by automatic assembly is given some default attribute values

Dependent annotations

  • @ SpringBootApplication: The annotation of the sb project application startup class is actually a combination of three annotations: @SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan, of which the second one

  • ## plays a role in automatic assembly. #@EnableAutoConfiguration: Indicates the function of SB application to start automatic assembly (including loading the corresponding Bean into the IOC container and assigning values ​​to properties according to the default configuration)

  • @Import(EnableAutoConfigurationImportSelector.class) : This annotation is quite powerful. You can forcibly register beans that are not registered in the IOC to the IOC, indicating that to start the automatic configuration function, you need to introduce EnableAutoConfigurationImportSelector.class

  • @Configuration

  • @ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class }): Indicates that for the RedisAutoConfiguration configuration class to work, there must be a jar package containing these classes.

  • @EnableConfigurationProperties(RedisProperties.class): Indicates that the configuration in RedisProperties.class is referenced by default

  • ##@ConditionalOnMissingBean(RedisConnectionFactory.class): This is very powerful Note, customization takes precedence when implementing automatic assembly. Indicates that the default JedisConnectionFactory will be used only if the user does not inject a custom RedisConnectionFactory.class class.

The process of automatic assembly

  • The dependency between classes is realized through various annotations. When the container starts, Application.run will Call the selectImports method of EnableAutoConfigurationImportSelector.class (actually the method of its parent class)

  • The selectImports method will eventually call the SpringFactoriesLoader.loadFactoryNames method to obtain a comprehensive list of commonly used BeanConfigurations

  • The loadFactoryNames method will read FACTORIES_RESOURCE_LOCATION (that is, spring.factories under spring-boot-autoconfigure.jar) and obtain the fully qualified ClassName of all Spring-related beans, about 120+

  • The selectImports method continues to call filter(configurations, autoConfigurationMetadata); at this time, it will be filtered one by one according to the conditions in these BeanConfigurations. The most important thing is @ConditionalOnClass. This conditional annotation will go to the classpath. Find whether there is this conditional dependency class in the jar package, so you must have the corresponding jar package to have these dependency classes and generate some default configuration beans required by the IOC environment

  • Finally, inject the qualified BeanConfiguration into the attribute value in the default EnableConfigurationPropertie class and inject it into the IOC environment

The above is the detailed content of What is the principle of java SpringBoot automatic assembly?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete