Основы SpringBoot
SpringBoot
может помочь нам лучше использоватьSpring
, быстрее настроить работающее приложение Spring.
SpringBoot
Запись, реализующая автоматическую настройку,@EnableAutoConfiguration
Аннотация, которая в свою очередь проходит@Import
Аннотации импортируютсяAutoConfigurationImportSelector
, в этом классе реализуетсяMETA-INF/spring.factories
серединаorg.springframework.boot.autoconfigure.EnableAutoConfiguration
Все конфигурации, заданные свойствами, такими какorg.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
.
//文件: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,\
В CacheAutoConfiguration через условную аннотацию@ConditionalOnXXX
,а также@Import
Аннотация для достижения корреляции функции кешаBean
автоматическая конфигурация.
// 文件: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()));
}
Реализуйте свою собственную автоконфигурацию
В реальном процессе разработки нам может понадобиться интегрировать в наш проект внутренние или сторонние библиотеки классов компании, которые официально не поддерживаются Spring. Но для повторного использования лучше настроить его по автонастройке SpringBoot.
Шаг 1. Внедрение официальных зависимостей Spring
POM-файл проекта:
<?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>
<!-- 和Spring官方的自动配置做区分 -->
<groupId>geektime.spring.hello</groupId>
<artifactId>geektime-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>geektime-spring-boot-autoconfigure</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.1.3.RELEASE</spring-boot.version>
</properties>
<!-- 引入Spring官方的配置管理 -->
<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>
<!-- 引入SpringBoot的自动配置模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 自己的定义第三方依赖 -->
<dependency>
<groupId>geektime.spring.hello</groupId>
<artifactId>greeting</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Шаг 2: Напишите конфигурацию Java и добавьте условные аннотации
Условные аннотации, поддерживаемые Spring:
- Условная аннотация @Conditional
- Условие класса @ConditionalOnClass, @ConditionalOnMissingClass
- Условие свойства @ConditionalOnProperty
- Условия компонента @ConditionalOnBean, @ConditionalOnMissingBean, @ConditionalOnSingleCandidate
- Состояние ресурса @ConditionalOnResource
- Условия использования веб-приложений @ Условие.
- Другие условия @ConditionalOnExpression, @ConditionalOnJava, @ConditionalOnJndi
Код конфигурации Java выглядит следующим образом:
@Configuration
@ConditionalOnClass(GreetingApplicationRunner.class)
public class GreetingAutoConfiguration {
@Bean
@ConditionalOnMissingBean(GreetingApplicationRunner.class)
@ConditionalOnProperty(name = "greeting.enabled", havingValue = "true", matchIfMissing = true)
public GreetingApplicationRunner greetingApplicationRunner() {
return new GreetingApplicationRunner();
}
}
Шаг 3: Автоматическая настройка позиционирования
в текущем проектеresource
в каталогеMETA-INF
Создан в каталогеspring.factories
файл со следующим содержимым:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
geektime.spring.hello.greeting.GreetingAutoConfiguration
Шаг 4: Определите порядок выполнения автоконфигурации
Основные аннотации:
- @AutoConfigureBefore
- @AutoConfigureAfter
- @AutoConfigureOrder
Обычно не требуется, пожалуйста, обратитесь к конкретному использованиюSpring официальная автоматическая конфигурация.
Как реализовать SpringBoot в старых версиях Spring, которые не поддерживают SpringBoot
Если вы реализуете функцию автоматической настройки, подобную SpringBoot в старой версии Spring, вам необходимо использовать механизм точки расширения Spring.Для принципа, пожалуйста, обратитесь к сообщению в блогеТочки расширения Spring Framework.
Добавьте конфигурацию:
@Configuration
public class GreetingAutoConfiguration {
@Bean
public static GreetingBeanFactoryPostProcessor greetingBeanFactoryPostProcessor() {
return new GreetingBeanFactoryPostProcessor();
}
}
пользовательскийBeanFactoryPostProcessor
Реализуйте функции, аналогичные условным аннотациям:
@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());
}
}
}