SpringBoot automatically configure annotation analytical principle

Turn: https: //www.cnblogs.com/wenbochang/p/9851314.html

1. SpringBoot Start main categories:

Copy the code
1 @SpringBootApplication
2 public class DemoApplication {
3     public static void main(String[] args) {
4 
5         SpringApplication.run(DemoApplication.class, args);
6     }
7 }
Copy the code

 

Every time we start this direct direct startup class, SpringBoot started a success, and helped us a lot configured to automatically configure class.

The most important is  @SpringBootApplication  this comment, we point to look into.

 

2. SpringBootApplication notes:

Copy the code
 1 @Target(ElementType.TYPE)
 2 @Retention(RetentionPolicy.RUNTIME)
 3 @Documented
 4 @Inherited
 5 @SpringBootConfiguration
 6 @EnableAutoConfiguration
 7 @ComponentScan(excludeFilters = {
 8         @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
 9         @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
10 public @interface SpringBootApplication {
Copy the code

 

  Three of the more important notes:

  • @SpringBootConfiguration: Spring Boot configuration class, marked on a class, said it was a Spring Boot configuration class

  • @EnableAutoConfiguration: enable automatic configuration class, the essence SpringBoot lies.

  • @ComponentScan Pack scan

  Things before we need to configure, Spring Boot to help us to automatically configure; @EnableAutoConfiguration tell SpringBoot turn on auto-configuration; the automatic configuration to take effect;

3. EnableAutoConfiguration notes:

Copy the code
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Inherited
5 @AutoConfigurationPackage
6 @Import(AutoConfigurationImportSelector.class)
7 public @interface EnableAutoConfiguration {
Copy the code

 

Two of the more important notes:

  • @AutoConfigurationPackage: Automatic configuration package

  • @Import: Component introduced autoconfiguration

 

4. AutoConfigurationPackage commentary:

Copy the code
1     static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
2 
3         @Override
4         public void registerBeanDefinitions(AnnotationMetadata metadata,
5                 BeanDefinitionRegistry registry) {
6             register(registry, new PackageImport(metadata).getPackageName());
7         }
Copy the code

 

It is actually registered the definition of a Bean.

new PackageImport (metadata) .getPackageName () , it is actually returned to the current of the main program of  the same level and a sub-level      package assembly.

 

 

FIG above as an example, DemoApplication demo package and is at the same level, but this class is DemoApplication demo2 parent, sibling, and the example package

In other words, DemoApplication the boot loader of the Bean, and does not load demo2, which is why we should DemoApplication on the most advanced projects.

 

5. Import(AutoConfigurationImportSelector.class)注解:

 

As can be seen from the figure  AutoConfigurationImportSelector inherited  DeferredImportSelector inherited ImportSelector 

ImportSelector there is a method: selectImports.

 

Copy the code
 1 @Override
 2     public String[] selectImports(AnnotationMetadata annotationMetadata) {
 3         if (!isEnabled(annotationMetadata)) {
 4             return NO_IMPORTS;
 5         }
 6         AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
 7                 .loadMetadata(this.beanClassLoader);
 8         AnnotationAttributes attributes = getAttributes(annotationMetadata);
 9         List<String> configurations = getCandidateConfigurations(annotationMetadata,
10                 attributes);
11         configurations = removeDuplicates(configurations);
12         Set<String> exclusions = getExclusions(annotationMetadata, attributes);
13         checkExcludedClasses(configurations, exclusions);
14         configurations.removeAll(exclusions);
15         configurations = filter(configurations, autoConfigurationMetadata);
16         fireAutoConfigurationImportEvents(configurations, exclusions);
17         return StringUtils.toStringArray(configurations);
18     }
Copy the code

 

You can see the ninth line, it is actually to load the   public static final String FACTORIES_RESOURCE_LOCATION = "META -INF / spring.factories"; external file. This external file, there are many types of auto-configuration. as follows:

 

 

6. How to customize your own Bean:

We RedisTemplate example:

Copy the code
 1 @Configuration
 2 @ConditionalOnClass(RedisOperations.class)
 3 @EnableConfigurationProperties(RedisProperties.class)
 4 @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
 5 public class RedisAutoConfiguration {
 6 
 7     @Bean
 8     @ConditionalOnMissingBean(name = "redisTemplate")
 9     public RedisTemplate<Object, Object> redisTemplate(
10             RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
11         RedisTemplate<Object, Object> template = new RedisTemplate<>();
12         template.setConnectionFactory(redisConnectionFactory);
13         return template;
14     }
15 
16     @Bean
17     @ConditionalOnMissingBean
18     public StringRedisTemplate stringRedisTemplate(
19             RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
20         StringRedisTemplate template = new StringRedisTemplate();
21         template.setConnectionFactory(redisConnectionFactory);
22         return template;
23     }
24 
25 }
Copy the code

 

我们每次在Spring中使用Redis,都会使用到RedisTemplate这个工具类,但是他默认给我们返回的这个工具类,可能不是很符合我们的要求。比如:我们想要开启事务,或者想要改变它默认的序列化。

这时候该如何去做呢?

根据前面的分析,只要我们在容器中放入一个RedisTemplate Bean即可。

 

Copy the code
 1 @Bean("redisTemplate")
 2     public RedisTemplate<Object, Object> myRedisTemplate(
 3             RedisConnectionFactory redisConnectionFactory) {
 4         RedisTemplate<Object, Object> template = new RedisTemplate<>();
 5         template.setConnectionFactory(redisConnectionFactory);
 6         // 修改序列化为Jackson
 7         template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
 8         // 开启事务
 9         template.setEnableTransactionSupport(true);
10         return template;
11     }
Copy the code

 

我们自己定义我们的RedisTemplate模板,修改序列化,开启事务等操作。

我们将我们自己的Bean加入到IoC容器中以后,他就会默认的覆盖掉原来的RedisTemplate,达到定制的效果。

 

我们在以Kafka为例:

假设我们想要消费的对象不是字符串,而是一个对象呢?比如Person对象,或者其他Object类呢?

1: We first went to look for KafkaAutoConfiguration (xxxAutoConfiguration) , see if there are about Serializer configuration properties

2: Suppose we did not go KafkaProperties find whether there is a file Serializer Configuration

 

 

 

Then directly application.properties modify the default serialization like, even Bean does not need to rewrite their own.

 Similarly this can be used to provide Json Spring serialized, serialization can automatically use the third-party framework, such Avro, Protobuff etc.

1 spring.kafka.producer.key-serializer=org.springframework.kafka.support.serializer.JsonSerializer
2 spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
3 spring.kafka.consumer.key-deserializer=com.example.common.MyJson
4 spring.kafka.consumer.value-deserializer=com.example.common.MyJson

 

Guess you like

Origin www.cnblogs.com/jvStarBlog/p/11275574.html