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

How to use compound annotation @ SpringBootApplication in Java

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article introduces the knowledge of "how to use compound annotations @ SpringBootApplication in Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Interested in the automatic configuration of the SpringBoot project, I learned its source code and sorted out some of its contents. If there are any mistakes, please correct me. Don't say much, just go to the source code.

The source code of @ SpringBootApplication annotation is as follows:

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan (excludeFilters = {@ Filter (type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @ Filter (type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)}) public @ interface SpringBootApplication {...}

You can see that this is a composite annotation, including a total of 7 different annotations, which are analyzed below.

Notes

Comment 1:@Target ({ElementType.TYPE})

It is used to indicate the scope of an annotation, and TYPE indicates that the scope is a class or interface.

Note 2:@Retention (RetentionPolicy.RUNTIME)

Note 3:@Documented

Indicates that this comment is recorded by javadoc.

Note 4:@Inherited

On the annotation, when the parent class adds the @ SpringBootApplication annotation, the subclass inherits the annotation (not valid for the interface's implementation class).

Note 5:@SpringBootConfiguration

The bottom layer is still @ Configuration annotation, and the source code is as follows:

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Configurationpublic @ interface SpringBootConfiguration {} Note 6:@ComponetScan

The @ ComponentScan annotation is important in Spring because its function corresponding to the element @ ComponentScan in the XML configuration is to automatically scan and load eligible components (such as @ Component and @ Repository, etc.) or bean definitions, eventually loading these bean definitions into the IoC container.

The scope of @ ComponentScan automatic scanning can be fine-grained through attributes such as basePackages, and if not specified, the default Spring framework implementation scans from the package that declares the class in which @ ComponentScan resides. Therefore, the startup class of SpringBoot is best placed under root package, because basePackages is not specified by default.

Note: @ EnableAutoConfiguration

The personal feeling that @ EnableAutoConfiguration is the most important Annotation can be summarized as follows: with the help of @ Import, all bean definitions that meet the automatic configuration criteria are loaded into the IoC container.

The source code is as follows:

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Inherited@AutoConfigurationPackage@Import (AutoConfigurationImportSelector.class) public @ interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class [] exclude () default {}; String [] excludeName () default {};}

You need to pay attention to @ AutoConfigurationPackage and @ Import (AutoConfigurationImportSelector.class) annotations here.

Comment: @ AutoConfigurationPackage

The source code is as follows

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Inherited@AutoConfigurationPackage@Import (AutoConfigurationImportSelector.class) public @ interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class [] exclude () default {}; String [] excludeName () default {};}

You can see that the core of this annotation is also the Import annotation, indicating that packages of the class tagging the annotation should be registered with AutoConfigurationPackages. Let's move on to the class Registrar:

Static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {@ Override / / metadata is the meta-information public void registerBeanDefinitions (AnnotationMetadata metadata, BeanDefinitionRegistry registry) {/ / registers all the components under our annotated package register (registry, new PackageImport (metadata). GetPackageName ());} @ Override public Set determineImports (AnnotationMetadata metadata) {return Collections.singleton (new PackageImport (metadata);}}

The core method in this class is the register method:

Private static final String BEAN = AutoConfigurationPackages.class.getName (); public static void register (BeanDefinitionRegistry registry, String...) PackageNames) {if (registry.containsBeanDefinition (BEAN)) {BeanDefinition beanDefinition = registry.getBeanDefinition (BEAN); ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues (); constructorArguments.addIndexedArgumentValue (0, addBasePackages (constructorArguments, packageNames));} else {GenericBeanDefinition beanDefinition = new GenericBeanDefinition (); beanDefinition.setBeanClass (BasePackages.class); beanDefinition.getConstructorArgumentValues (). AddIndexedArgumentValue (0, packageNames); beanDefinition.setRole (BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition (BEAN, beanDefinition) }}

The logic of the register method is clear: if the bean is already registered, get its constructor parameter value and add the package name; otherwise, create a new bean definition and register it. With the @ AutoConfigurationPackage annotation, you can register all the components under the package where the annotation is located.

Note: @ Import (AutoConfigurationImportSelector.class)

This annotation imports the AutoConfigurationImportSelector class. The core method of this class is the selectImports method, which implements the ImportSelector interface. The method is imported based on the jar package and components that we configured in the pom.xml file. So the method returns a full-path String array of Class, and the returned Class is managed by the Spring container. The source code of the method is as follows:

@ Overridepublic String [] selectImports (AnnotationMetadata annotationMetadata) {if (! isEnabled (annotationMetadata)) {return NO_IMPORTS;} AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadmetadata (this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry (autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray (autoConfigurationEntry.getConfigurations ());}

The structure of this method is also very clear. First, use the isEnabled method to determine whether you need to import, if you need to import, get the configuration information through the loadMetadata method, and automatically assemble it through getAutoConfigurationEntry. The source code of isEnabled method is as follows:

Protected boolean isEnabled (AnnotationMetadata metadata) {if (getClass () = = AutoConfigurationImportSelector.class) {return getEnvironment () .getProperty (EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);} return true;}

This method determines whether automatic configuration is required through the configuration item EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, which defaults to true. The source code of loadMetadata method is as follows:

Protected static final String PATH = "META-INF/" + "spring-autoconfigure-metadata.properties"; public static AutoConfigurationMetadata loadMetadata (ClassLoader classLoader) {return loadMetadata (classLoader, PATH);} static AutoConfigurationMetadata loadMetadata (ClassLoader classLoader, String path) {try {Enumeration urls = (classLoader! = null)? ClassLoader.getResources (path): ClassLoader.getSystemResources (path); Properties properties = new Properties (); while (urls.hasMoreElements ()) {properties.putAll (PropertiesLoaderUtils.loadProperties (new UrlResource (urls.nextElement ();} return loadMetadata (properties);} catch (IOException ex) {throw new IllegalArgumentException ("Unable to load @ ConditionalOnClass location [" + path + "], ex) }} static AutoConfigurationMetadata loadMetadata (Properties properties) {return new PropertiesAutoConfigurationMetadata (properties);}

You can see that this method loads all the configuration information under META-INF/spring-autoconfigure-metadata.properties and returns it as an AutoConfigurationMetadata object.

Note: the spring-autoconfigure-metadata.properties file is under spring-boot-autoconfigure-2.1.9.RELEASE.jar/META-INF.

The source code of getAutoConfigurationEntry method is as follows:

Protected AutoConfigurationEntry getAutoConfigurationEntry (AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {if (! isEnabled (annotationMetadata)) {return EMPTY_ENTRY;} AnnotationAttributes attributes = getAttributes (annotationMetadata); List configurations = getCandidateConfigurations (annotationMetadata, attributes); configurations = removeDuplicates (configurations); Set exclusions = getExclusions (annotationMetadata, attributes); checkExcludedClasses (configurations, exclusions); configurations.removeAll (exclusions); configurations = filter (configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents (configurations, exclusions); return new AutoConfigurationEntry (configurations, exclusions);}

This method is the main flow method of AutoConfiguration, and each line of this method can be regarded as a step, so the processing steps are as follows:

1. Load the attribute value getAttribute method configured with the @ EnableAutoConfiguration annotation:

Protected AnnotationAttributes getAttributes (AnnotationMetadata metadata) {String name = getAnnotationClass (). GetName (); AnnotationAttributes attributes = AnnotationAttributes.fromMap (metadata.getAnnotationAttributes (name, true)); Assert.notNull (attributes, ()-> "No auto-configuration attributes found. Is" + metadata.getClassName () + "annotated with" + ClassUtils.getShortName (name) + "?); return attributes;}

two。 Get the value,getCandidateConfigurations method in the META-INF/spring.factories file that does key with the @ EnableAutoConfiguration fully qualified class name:

Protected List getCandidateConfigurations (AnnotationMetadata metadata, AnnotationAttributes attributes) {List configurations = SpringFactoriesLoader.loadFactoryNames (getSpringFactoriesLoaderFactoryClass (), getBeanClassLoader ()); Assert.notEmpty (configurations, "No auto configuration classes found in META-INF/spring.factories. If you" + "are using a custom packaging, make sure that file is correct."); return configurations;} protected Class getSpringFactoriesLoaderFactoryClass () {return EnableAutoConfiguration.class;}

Where the SpringFactoriesLoader.loadFactoryNames () method loads the fully qualified class name of the factory implementation of the given type from META-INF/spring.factories using the given class loader

3. Deweighting

4. Get the class names of the classes that need to be excluded, which can be configured in the @ EnableAutoConfiguration annotation

5. Check these two sets

6. Remove classes that need to be excluded

7. Filter according to OnBeanCondition, OnClassCondition and other conditions (if you are interested, you can learn more about it)

8. Broadcast events, get all the implementation classes of AutoConfigurationImportListener, and then generate events for broadcast

9. The fully qualified names of the classes that need to be assembled and excluded are encapsulated as AutoConfigurationEntry object returns.

Therefore, @ EnableAutoConfiguration can be summarized as follows: search for all META-INF/spring.factories configuration files in classpath, and instantiate the configuration items corresponding to EnableAutoConfiguration into the corresponding IoC container configuration classes labeled @ Configuration through reflection, and load them into the IoC container.

This is the end of the content of "how to use compound annotations @ SpringBootApplication in Java". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

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

Development

Wechat

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

12
Report