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 configure automatic loading for Springboot

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

Share

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

Editor to share with you how to configure Springboot automatic loading, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!

1. A preliminary study on the principle of springboot automatic configuration

The following notes are in springboot's Automation configuration package: spring-boot-autoconfigure. Readers can follow the steps again, should have a certain understanding of automatic configuration.

The entry of the 1.springboot program is in the startup class, which has a key annotation SpringBootApplication

@ 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 {/ / slightly }

two。 Open the SpringBootApplication comment, and there is a key note EnableAutoConfiguration

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Inherited@AutoConfigurationPackage@Import (AutoConfigurationImportSelector.class) public @ interface EnableAutoConfiguration {/ / }

There is a @ Import (AutoConfigurationImportSelector.class) on 3.EnableAutoConfiguration. Notice AutoConfigurationImportSelector.

The @ Import function creates a bean object for AutoConfigurationImportSelector and joins the IoC container

/ / org.springframework.boot.autoconfigure.AutoConfigurationImportSelector// only the key methods 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;}

The getCandidateConfigurations method code in the 4.AutoConfigurationImportSelector class is like this, which calls the loadFactoryNames method of SpringFactoriesLoader to get the

Configurations, this configurations list is actually the class to be configured by automatic flowers. Two important methods of SpringFactoriesLoader are as follows:

/ / org.springframework.core.io.support.SpringFactoriesLoader// only posts two key methods public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories" / / this method returns the fully qualified class name of the class to be configured automatically, which is configured from META-INF/spring.factories. There is an org.springframework.boot.autoconfigure.EnableAutoConfiguration in the configuration file followed by multiple classes public static List loadFactoryNames (Class factoryType, @ Nullab, etc.) {String factoryTypeName = factoryType.getName (); return loadSpringFactories (classLoader) .getOrDefault (factoryTypeName, Collections.emptyList ()) that you want to be configured automatically. } private static Map loadSpringFactories (@ Nullable ClassLoader classLoader) {MultiValueMap result = cache.get (classLoader); if (result! = null) {return result;} try {Enumeration urls = (classLoader! = null? ClassLoader.getResources (FACTORIES_RESOURCE_LOCATION): ClassLoader.getSystemResources (FACTORIES_RESOURCE_LOCATION); / / META-INF/spring.factories result = new LinkedMultiValueMap (); while (urls.hasMoreElements ()) {URL url = urls.nextElement () UrlResource resource = new UrlResource (url); Properties properties = PropertiesLoaderUtils.loadProperties (resource); for (Map.Entry entry: properties.entrySet ()) {String factoryTypeName = ((String) entry.getKey ()) .trim () For (String factoryImplementationName: StringUtils.commaDelimitedListToStringArray ((String) entry.getValue () {result.add (factoryTypeName, factoryImplementationName.trim ()) } cache.put (classLoader, result); return result } catch (IOException ex) {throw new IllegalArgumentException ("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);}}

5. For example, we can see in spring.factories that there is an org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration after org.springframework.boot.autoconfigure.EnableAutoConfiguration, indicating that springboot wants redis to be configured automatically. Then we open the RedisAutoConfiguration source code to see. Here I deliberately did not copy the source code, with the screenshot, you can see that the screenshot directly reported errors, compilation errors, the reason for the error is that we have not added spring-boot-starter-data-redis dependencies. * * here is a question: why does our project still start when it is clear that the code is wrong and Cannot resolve symbol xxx (class not found)? Do not believe that you set up a simple springboot project, only add web dependencies, manually open RedisAutoConfiguration, and find that it is a red error, but you start the project and find that there is no problem, why?? * * this question will be answered later. Let's move on to the question of automatic configuration.

6. First copy the RedisAutoConfiguration source code to make it easier for me to write comments. The screenshot above is mainly used to let you see the error report.

@ Configuration (proxyBeanMethods = false) @ ConditionalOnClass (RedisOperations.class) @ EnableConfigurationProperties (RedisProperties.class) @ Import ({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class}) public class RedisAutoConfiguration {@ Bean @ ConditionalOnMissingBean (name = "redisTemplate") public RedisTemplate redisTemplate (RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate template = new RedisTemplate (); template.setConnectionFactory (redisConnectionFactory); return template } @ Bean @ ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate (RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {StringRedisTemplate template = new StringRedisTemplate (); template.setConnectionFactory (redisConnectionFactory); return template;}}

Look at the source code to see that there is a Configuration and ConditionalOnClass annotations on RedisAutoConfiguration. Analyze these two first. First of all, the Configuration annotation means that this is a Java config configuration class, and the xml file of spring configuration bean is used to instantiate bean. * * but note that there is also a @ ConditionalOnClass (RedisOperations.class) annotation, which will not take effect until the class RedisOperations.class is found. If this class is not found, then the entire RedisAutoConfiguration will not take effect. * * so when we introduce the redis dependency, springboot will first set a default redis configuration for us through the RedisAutoConfiguration method redisTemplate. Of course, there is also a note @ ConditionalOnMissingBean (name = "redisTemplate") on this method, that is, when we do not manually configure the bean of redisTemplate, it will call this default method and inject a redisTemplate into the IoC container, so we usually configure the redisTemplate manually to facilitate us to set the serializer as follows:

@ Configurationpublic class RedisConfig {/ * set the serialization settings for redisTemplate * * @ param redisConnectionFactory * @ return * / @ Bean public RedisTemplate redisTemplate (RedisConnectionFactory redisConnectionFactory) {/ / 1. Create redisTemplate template RedisTemplate template = new RedisTemplate (); / / 2. Associate redisConnectionFactory template.setConnectionFactory (redisConnectionFactory); / / 3. Create the serialization class Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer (Object.class); ObjectMapper om = new ObjectMapper (); / / 4. Set visibility om.setVisibility (PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); / / 5. Start the default type om.enableDefaultTyping (ObjectMapper.DefaultTyping.NON_FINAL); / / 6. Serialization class, object mapping setting jackson2JsonRedisSerializer.setObjectMapper (om); / / 7. Set the conversion format of value and key template.setValueSerializer (jackson2JsonRedisSerializer); template.setKeySerializer (new StringRedisSerializer ()); template.afterPropertiesSet (); return template;}}

There are also two comments on RedisAutoConfiguration to read redis-related information, ip, port, password, etc., from the configuration file.

EnableConfigurationProperties (RedisProperties.class) @ Import ({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class}) 2. Supplementary extension (explain why all referenced packages have red errors and the project can still be started)

All @ Condition annotations (including derivatives) actually correspond to a specific implementation, which has a judgment method called matches, which returns a Boolean type judgment value.

Open the ConditionalOnClass source code as follows, and its Conditional annotation passes an OnClassCondition.class, which is its corresponding judgment class, that is, when we use ConditionalOnClass annotation, it actually calls OnClassCondition to judge.

Target ({ElementType.TYPE, ElementType.METHOD}) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Conditional (OnClassCondition.class) public @ interface ConditionalOnClass {/ * The classes that must be present. Since this annotation is parsed by loading class * bytecode, it is safe to specify classes here that may ultimately not be on the * classpath, only if this annotation is directly on the affected component and * not if this annotation is used as a composed, meta-annotation. In order to * use this annotation as a meta-annotation, only use the {@ link # name} attribute. * @ return the classes that must be present * / Class [] value () default {}; / * The classes names that must be present. * @ return the class names that must be present. * / String [] name () default {};}

The ConditionalOnClass class diagram is as follows, which inherits the condition interface

Open the Condition API as follows and check the comments. It is stated in the comments that * * the condition judgment is carried out before the bean definition is about to register with the container. * * students who have seen the springIoC source code should know that when the service starts, spring first reads the xml configuration file (or through annotations), defines a BeanDefinition according to the configuration file, and then puts the bean into the container (it is actually a Map in spring). Then, according to the bean definition, the real object is created through reflection. Reflection triggers class loading. When the condition condition is not met, according to the following notes, the bean definition is blocked and cannot even be registered, so it is naturally impossible to create an object through reflection, and class loading will not be triggered without reflection. If RedisAutoConfiguration is not triggered, then of course, ah, it will not load, so even if it references a non-existent class, there will be no problem.

The above is all the contents of the article "how to configure Springboot to load automatically". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

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