Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Notes on SpringBoot Automation configuration and what is the switch principle

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the notes of SpringBoot automation configuration and the switch principle. The content is very detailed. Interested friends can use it for reference. I hope it will be helpful to you.

FreeMarkerAutoConfiguration, this automated configuration class requires that some classes in classloader need to exist and load after other configuration classes.

Automatic configuration principle of SpringBoot

Http://fangjian0423.github.io/2016/06/12/springboot-autoconfig-analysis/

However, there are also some automated configuration classes that need to be used with some annotation switches to take effect. For example, @ EnableBatchProcessing annotations in spring-boot-starter-batch, @ EnableCaching, etc.

A need.

Before analyzing how these switches work, let's look at a requirement:

Define an Annotation that allows applications that use this Annotaion to automatically inject classes or do some underlying things.

We will use the @ Import annotation provided by Spring with a configuration class to do this.

Let's complete this requirement with the simplest example: define an annotation EnableContentService, and the program that uses this annotation will automatically inject the bean of ContentService.

@ Retention (RetentionPolicy.RUNTIME)

@ Target (ElementType.TYPE)

@ Import (ContentConfiguration.class)

Public @ interface EnableContentService {}

Public interface ContentService {

Void doSomething ()

}

Public class SimpleContentService implements ContentService {

@ Override

Public void doSomething () {

System.out.println ("do some simple things")

}

}

Then add the @ EnableContentService annotation to the entry of the application.

In that case, ContentService is injected into it. SpringBoot is also done with this. It just uses a more advanced ImportSelector.

The use of ImportSelector

After using ImportSelector, we can add some properties to the Annotation, and then load different bean depending on the properties.

We add the attribute policy to the @ EnableContentService annotation and Import a Selector.

@ Retention (RetentionPolicy.RUNTIME)

@ Target (ElementType.TYPE)

@ Import (ContentImportSelector.class)

Public @ interface EnableContentService {

String policy () default "simple"

}

This ContentImportSelector loads different bean according to the policy in the EnableContentService annotation.

Public class ContentImportSelector implements ImportSelector {

@ Override

Public String [] selectImports (AnnotationMetadata importingClassMetadata) {

Class annotationType = EnableContentService.class

AnnotationAttributes attributes = AnnotationAttributes.fromMap (importingClassMetadata.getAnnotationAttributes (

AnnotationType.getName (), false))

String policy = attributes.getString ("policy")

If ("core" .equals (policy)) {

Return new String [] {CoreContentConfiguration.class.getName ()}

} else {

Return new String [] {SimpleContentConfiguration.class.getName ()}

}

}

}

CoreContentService and CoreContentConfiguration are as follows:

Public class CoreContentService implements ContentService {

@ Override

Public void doSomething () {

System.out.println ("do some import things")

}

}

Public class CoreContentConfiguration {

@ Bean

Public ContentService contentService () {

Return new CoreContentService ()

}

}

In this way, if you use core in the policy annotated by @ EnableContentService, the application will automatically load CoreContentService, otherwise it will load SimpleContentService.

The use of ImportSelector in SpringBoot

The ImportSelector in SpringBoot is done through the @ EnableAutoConfiguration annotation provided by SpringBoot.

This @ EnableAutoConfiguration annotation can be called explicitly, otherwise it will be called implicitly in the @ SpringBootApplication annotation.

EnableAutoConfigurationImportSelector is used as the ImportSelector in the @ EnableAutoConfiguration annotation. The following code is the specific code for selection in EnableAutoConfigurationImportSelector:

@ Override

Public String [] selectImports (AnnotationMetadata metadata) {

Try {

AnnotationAttributes attributes = getAttributes (metadata)

List configurations = getCandidateConfigurations (metadata

Attributes)

Configurations = removeDuplicates (configurations); / / Delete duplicate configuration

Set exclusions = getExclusions (metadata, attributes); / / remove the configuration that requires exclude

Configurations.removeAll (exclusions)

Configurations = sort (configurations); / / sort

RecordWithConditionEvaluationReport (configurations, exclusions)

Return configurations.toArray (new String [configurations.size ()])

}

Catch (IOException ex) {

Throw new IllegalStateException (ex)

}

}

Where the getCandidateConfigurations method gets the configuration class:

Protected List getCandidateConfigurations (AnnotationMetadata metadata

AnnotationAttributes attributes) {

Return SpringFactoriesLoader.loadFactoryNames (

GetSpringFactoriesLoaderFactoryClass (), getBeanClassLoader ()

}

The SpringFactoriesLoader.loadFactoryNames method reads the META-INF/spring.factories file information from all jar packages based on the static variable FACTORIES_RESOURCE_LOCATION:

Public static List loadFactoryNames (Class factoryClass, ClassLoader classLoader) {

String factoryClassName = factoryClass.getName ()

Try {

Enumeration urls = (classLoader! = null? ClassLoader.getResources (FACTORIES_RESOURCE_LOCATION):

ClassLoader.getSystemResources (FACTORIES_RESOURCE_LOCATION))

List result = new ArrayList ()

While (urls.hasMoreElements ()) {

URL url = urls.nextElement ()

Properties properties = PropertiesLoaderUtils.loadProperties (new UrlResource (url))

String factoryClassNames = properties.getProperty (factoryClassName); / / only values with key as factoryClassNames will be filtered.

Result.addAll (Arrays.asList (StringUtils.commaDelimitedListToStringArray (factoryClassNames)

}

Return result

}

Catch (IOException ex) {

Throw new IllegalArgumentException ("Unable to load [" + factoryClass.getName () +)

"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex)

}

}

The getSpringFactoriesLoaderFactoryClass method in the getCandidateConfigurations method returns EnableAutoConfiguration.class, so the value of key as org.springframework.boot.autoconfigure.EnableAutoConfiguration is filtered.

The following configuration code is part of the spring.factories file in autoconfigure, the jar package (there is a key of org.springframework.boot.autoconfigure.EnableAutoConfiguration, so you get these AutoConfiguration):

# Initializers

Org.springframework.context.ApplicationContextInitializer=\

Org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

# Application Listeners

Org.springframework.context.ApplicationListener=\

Org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configure

Org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

Org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\

Org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

Org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\

Org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\

Of course, not all of these AutoConfiguration will be loaded, and it will be determined whether or not to load according to conditions such as @ ConditionalOnClass on the AutoConfiguration.

In the above example, reading the properties file will only filter out the value of key as org.springframework.boot.autoconfigure.EnableAutoConfiguration.

There are other key inside SpringBoot to filter to get the classes that need to be loaded:

Org.springframework.test.context.TestExecutionListener

Org.springframework.beans.BeanInfoFactory

Org.springframework.context.ApplicationContextInitializer

Org.springframework.context.ApplicationListener

Org.springframework.boot.SpringApplicationRunListener

Org.springframework.boot.env.EnvironmentPostProcessor

Org.springframework.boot.env.PropertySourceLoader

On the SpringBoot automation configuration notes and how the switch principle is shared here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report