SpringBoot fundamentals
SpringBoot can help us make better use of Spring and configure a running Spring application faster.
SpringBoot automatic configuration is the entrance to the @ EnableAutoConfiguration annotations, the annotations by @ Import annotations Import AutoConfigurationImportSelector, In this class implements the meta-inf/spring. The factories in the org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration attribute specifies all the configuration, Such as org. Springframework. Boot. Autoconfigure. Cache. CacheAutoConfiguration.
// File: spring-boot-autoconfigure-2.1.3.release.jar! /META-INF/spring.factories# 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.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
Copy the code
In CacheAutoConfiguration, the conditional annotation @conditionalonxxx and the @import annotation are used to automatically configure related beans for caching functionality.
// File: spring-boot-autoconfigure-2.1.3. release-sources.jar! /org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java @Configuration @ConditionalOnClass(CacheManager.class) @ConditionalOnBean(CacheAspectSupport.class) @ConditionalOnMissingBean(value = CacheManager.class, name ="cacheResolver") @EnableConfigurationProperties(CacheProperties.class) @AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class }) @Import(CacheConfigurationImportSelector.class) public class CacheAutoConfiguration { @Bean @ConditionalOnMissingBean public CacheManagerCustomizers cacheManagerCustomizers( ObjectProvider<CacheManagerCustomizer<? >> customizers) {return new CacheManagerCustomizers(
customizers.orderedStream().collect(Collectors.toList()));
}
Copy the code
Implement your own AutoConfiguration
During actual development, we may need to integrate third-party libraries that are either in-house or not officially supported by Spring into our project. But for reuse, it is best to follow SpringBoot’s automatic configuration.
Step 1: Introduce Spring official dependencies
Pom files for the project:
<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > <! <groupId>geektime.spring. Hello </groupId> < artifactId > geektime - spring - the boot - autoconfigure < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > <name>geektime-spring-boot-autoconfigure</name> <description>Demo projectforSpring Boot < / description > < properties > < Java version > 1.8 < / Java version > < spring - the boot version > 2.1.3. RELEASE < / spring - the boot. Version > < / properties > <! <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version>
<type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <! <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <! Hello </groupId> <artifactId> Greeting </artifactId> <version>0.0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies> </project>Copy the code
Step 2: Write Java Configuration and add conditional annotations
Conditional comments supported by Spring:
- Conditional annotation @Conditional
- @ ConditionalOnClass class conditions, @ ConditionalOnMissingClass
- Attribute condition@conditionalonProperty
- @ ConditionalOnBean Bean conditions, @ ConditionalOnMissingBean, @ ConditionalOnSingleCandidate
- Conditioncondition@conditionalonResource
- @ ConditionalOnWebApplication Web applications use conditions, @ ConditionalOnNotWebApplication
- Other conditions @conditionalonexpression, @conditionalonJava, @conditionalonjndi
The Java Configuration code is as follows:
@Configuration
@ConditionalOnClass(GreetingApplicationRunner.class)
public class GreetingAutoConfiguration {
@Bean
@ConditionalOnMissingBean(GreetingApplicationRunner.class)
@ConditionalOnProperty(name = "greeting.enabled", havingValue = "true", matchIfMissing = true)
public GreetingApplicationRunner greetingApplicationRunner() {
returnnew GreetingApplicationRunner(); }}Copy the code
Step 3: Locate automatic configuration
Under the meta-INF directory of the current project, create a Spring. factories file like this:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
geektime.spring.hello.greeting.GreetingAutoConfiguration
Copy the code
Step 4: Define the order in which the automatic configuration is executed
The main notes are:
- @AutoConfigureBefore
- @AutoConfigureAfter
- @AutoConfigureOrder
Generally, this is not required. For details, see the official Spring automatic configuration.
How to implement SpringBoot in older versions of Spring that do not support SpringBoot
If you implement springboot-like automatic configuration in older versions of Spring, you need to use Spring’s extension point mechanism. For details, see the Spring framework extension point blog.
Add a Configuration:
@Configuration
public class GreetingAutoConfiguration {
@Bean
public static GreetingBeanFactoryPostProcessor greetingBeanFactoryPostProcessor() {
returnnew GreetingBeanFactoryPostProcessor(); }}Copy the code
Define a BeanFactoryPostProcessor that implements similar conditional annotations:
@Slf4j
public class GreetingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
boolean hasClass = ClassUtils.isPresent("geektime.spring.hello.greeting.GreetingApplicationRunner",
GreetingBeanFactoryPostProcessor.class.getClassLoader());
if(! hasClass) { log.info("GreetingApplicationRunner is NOT present in CLASSPATH.");
return;
}
if (beanFactory.containsBeanDefinition("greetingApplicationRunner")) {
log.info("We already have a greetingApplicationRunner bean registered.");
return;
}
register(beanFactory);
}
private void register(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory instanceof BeanDefinitionRegistry) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(GreetingApplicationRunner.class);
((BeanDefinitionRegistry) beanFactory)
.registerBeanDefinition("greetingApplicationRunner",
beanDefinition);
} else {
beanFactory.registerSingleton("greetingApplicationRunner", new GreetingApplicationRunner()); }}}Copy the code
The resources
- Extension points of the Spring framework
- Spring Family bucket video course SpringBoot
- Spring family bucket course code