Springboot source code parsing: implements automatic spring boot configuration and spring boot source code
The last two articles show how to implement automatic spring boot configuration and condition annotation. Based on the previous two articles, this article implements automatic spring boot configuration and uses condition annotations.
Requirement: add your own handwritten jar. You can use StringRedisTemplate directly.
1. Create a maven project. pom. xml is as follows:
4.0.0
com.share1024
redis
0.0.1-SNAPSHOT
jar
redis
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.10.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-configuration-processor
true
Create RedisProperties. java class
package com.share1024;import org.springframework.boot.context.properties.ConfigurationProperties;/** * @author : yesheng * @Description : * @Date : 2018/2/26 */@ConfigurationProperties(prefix = "custom.redis")public class RedisProperties { private int maxTotal; private int maxIdle; private long maxWait; private String host; private int port = 6379; private int timeout; public int getMaxTotal() { return maxTotal; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public int getMaxIdle() { return maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public long getMaxWait() { return maxWait; } public void setMaxWait(long maxWait) { this.maxWait = maxWait; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; }}
Here we use @ ConfigurationProperties (prefix = "custom. redis"), that is, the configuration in our application. yml/application. properties starts with custom. redis.
That is, convert properties to bean.
The configuration constant can be obtained using @ Value or Environment.
The constant configuration of redis has been written.
Create RedisAutoConfiguration. java class
package com.share1024;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPoolConfig;/** * @author : yesheng * @Description : * @Date : 2018/2/26 */@Configuration@ConditionalOnClass({RedisTemplate.class, Jedis.class})@EnableConfigurationProperties(RedisProperties.class)@ConditionalOnProperty(prefix = "custom.redis",name = "host")public class RedisAutoConfiguration { @Bean public StringRedisTemplate stringRedisTemplate(JedisConnectionFactory jedisConnectionFactory){ StringRedisTemplate redisTemplate = new StringRedisTemplate(); redisTemplate.setConnectionFactory(jedisConnectionFactory); return redisTemplate; } @Bean public JedisPoolConfig jedisPoolConfig(RedisProperties redisProperties){ JedisPoolConfig poolConfig = new JedisPoolConfig(); if(redisProperties.getMaxTotal() !=0){ poolConfig.setMaxTotal(redisProperties.getMaxTotal()); } if(redisProperties.getMaxIdle() !=0){ poolConfig.setMaxIdle(redisProperties.getMaxIdle()); } if(redisProperties.getMaxWait()!=0){ poolConfig.setMaxWaitMillis(redisProperties.getMaxWait()); } return poolConfig; } @Bean public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig,RedisProperties redisProperties){ JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig); jedisConnectionFactory.setHostName(redisProperties.getHost()); jedisConnectionFactory.setPort(redisProperties.getPort()); if(redisProperties.getTimeout() !=0){ jedisConnectionFactory.setTimeout(redisProperties.getTimeout()); } return jedisConnectionFactory; }}
@ ConditionalOnClass ({RedisTemplate. class, Jedis. class })
To register this class to the container, you must find RedisTemplate. class and Jedis. class in the context of the project. Without these two classes, no configuration is made.
@ EnableConfigurationProperties (RedisProperties. class)
Make the @ ConfigurationProperties annotation take effect
@ ConditionalOnProperty (prefix = "custom. redis", name = "host ")
This is what we need in application. properties custom. redis. host.
The three @ beans in the file are used when the automatic configuration class meets the above @ ConditionalOnClass ({RedisTemplate. class, Jedis. class })
And @ ConditionalOnProperty (prefix = "custom. redis ", name =" host "), the class will be registered to the spring container, and all the @ beans under the class will be registered to the container.
In this way, we can directly use StringRedisTemplate
Create a META-INF/spring. factories in the resources Directory
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.share1024.RedisAutoConfiguration
The previous article explains how to use EnableAutoConfigurationImportSelector. class in @ EnableAutoConfiguration. Repeat the process.
ConfigurationClassPostProcessor goes back to scan @ Component in the lifecycle.
Then recursively scan @ ImportResource, @ PropertySource, @ ComponentScan, @ Bean, @ Import in the class. Processing is complete.
@ EnableAutoConfiguration
With @ Import (EnableAutoConfigurationImportSelector. class), The META-INF/spring. factories will be scanned
All org. springframework. boot. autoconfigure. EnableAutoConfiguration. For further scanning.
Complete.
mvn clean install
Create a new project. Introduce the package project
@Autowired private StringRedisTemplate redisTemplate;
That's easy.
Most of the time we want to expand spring functions, we can also start from this direction. For example, Ctrip's apollo framework is also like this. If you are interested, you can study it.
Some time ago, springCloud finished its research and many people said that the source code could not be understood. I said it was very simple. What springcloud could not understand was springboot source code. Especially the first two articles. Have the opportunity to analyze the springcloud source code.