GH-264 - Only register EventPublicationRegistry if EventPublicationRepository present.
We now clearly separate between strict configuration, usable via @EnablePersistentDomainEvents and the auto-configuration for EventPublicationRegistry infrastructure. This allows using the core JAR in scenarios, in which no registry functionality is needed.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2017-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.modulith.events.config;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Shutdown;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncEnablingConfiguration;
|
||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.modulith.events.support.CompletionRegisteringAdvisor;
|
||||
import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
|
||||
import org.springframework.scheduling.annotation.AbstractAsyncConfiguration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* Fundamental configuration for the {@link EventPublicationRegistry} support.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @author Björn Kieling
|
||||
* @author Dmitry Belyaev
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@Import(AsyncEnablingConfiguration.class)
|
||||
public class EventPublicationAutoConfiguration extends EventPublicationConfiguration {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnBean(EventPublicationRepository.class)
|
||||
EventPublicationRegistry eventPublicationRegistry(EventPublicationRepository repository,
|
||||
ObjectProvider<Clock> clock) {
|
||||
return super.eventPublicationRegistry(repository, clock);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnBean(EventPublicationRegistry.class)
|
||||
static PersistentApplicationEventMulticaster applicationEventMulticaster(
|
||||
ObjectFactory<EventPublicationRegistry> eventPublicationRegistry, ObjectFactory<Environment> environment) {
|
||||
|
||||
return EventPublicationConfiguration.applicationEventMulticaster(eventPublicationRegistry, environment);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnBean(EventPublicationRegistry.class)
|
||||
static CompletionRegisteringAdvisor completionRegisteringAdvisor(ObjectFactory<EventPublicationRegistry> registry) {
|
||||
return EventPublicationConfiguration.completionRegisteringAdvisor(registry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnProperty(
|
||||
name = "spring.modulith.default-async-termination",
|
||||
havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
static AsyncPropertiesDefaulter asyncPropertiesDefaulter(Environment environment) {
|
||||
return new AsyncPropertiesDefaulter(environment);
|
||||
}
|
||||
|
||||
@EnableAsync
|
||||
@ConditionalOnMissingBean(AbstractAsyncConfiguration.class)
|
||||
static class AsyncEnablingConfiguration {}
|
||||
|
||||
static class AsyncPropertiesDefaulter implements BeanPostProcessor {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncPropertiesDefaulter.class);
|
||||
private static final String PROPERTY = "spring.task.execution.shutdown.await-termination";
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
AsyncPropertiesDefaulter(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (!(bean instanceof TaskExecutionProperties p)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (anyPropertyConfigured(PROPERTY, PROPERTY + "-period")) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
LOGGER.debug("Defaulting async shutdown to await termination in 2 seconds.");
|
||||
|
||||
Shutdown shutdown = p.getShutdown();
|
||||
|
||||
shutdown.setAwaitTermination(true);
|
||||
shutdown.setAwaitTerminationPeriod(Duration.ofSeconds(2));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private boolean anyPropertyConfigured(String... properties) {
|
||||
|
||||
return Arrays.stream(properties)
|
||||
.anyMatch(it -> environment.containsProperty(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,33 +16,19 @@
|
||||
package org.springframework.modulith.events.config;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Shutdown;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.modulith.events.config.EventPublicationConfiguration.AsyncEnablingConfiguration;
|
||||
import org.springframework.modulith.events.core.DefaultEventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.modulith.events.support.CompletionRegisteringAdvisor;
|
||||
import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
|
||||
import org.springframework.scheduling.annotation.AbstractAsyncConfiguration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* Fundamental configuration for the {@link EventPublicationRegistry} support.
|
||||
@@ -52,7 +38,6 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
* @author Dmitry Belyaev
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(AsyncEnablingConfiguration.class)
|
||||
class EventPublicationConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -76,61 +61,4 @@ class EventPublicationConfiguration {
|
||||
static CompletionRegisteringAdvisor completionRegisteringAdvisor(ObjectFactory<EventPublicationRegistry> registry) {
|
||||
return new CompletionRegisteringAdvisor(registry::getObject);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ConditionalOnProperty(
|
||||
name = "spring.modulith.default-async-termination",
|
||||
havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
static AsyncPropertiesDefaulter asyncPropertiesDefaulter(Environment environment) {
|
||||
return new AsyncPropertiesDefaulter(environment);
|
||||
}
|
||||
|
||||
@EnableAsync
|
||||
@ConditionalOnMissingBean(AbstractAsyncConfiguration.class)
|
||||
static class AsyncEnablingConfiguration {}
|
||||
|
||||
static class AsyncPropertiesDefaulter implements BeanPostProcessor {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncPropertiesDefaulter.class);
|
||||
private static final String PROPERTY = "spring.task.execution.shutdown.await-termination";
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
AsyncPropertiesDefaulter(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (!(bean instanceof TaskExecutionProperties p)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (anyPropertyConfigured(PROPERTY, PROPERTY + "-period")) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
LOGGER.debug("Defaulting async shutdown to await termination in 2 seconds.");
|
||||
|
||||
Shutdown shutdown = p.getShutdown();
|
||||
|
||||
shutdown.setAwaitTermination(true);
|
||||
shutdown.setAwaitTerminationPeriod(Duration.ofSeconds(2));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private boolean anyPropertyConfigured(String... properties) {
|
||||
|
||||
return Arrays.stream(properties)
|
||||
.anyMatch(it -> environment.containsProperty(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
org.springframework.modulith.events.config.EventPublicationConfiguration
|
||||
org.springframework.modulith.events.config.EventPublicationAutoConfiguration
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.modulith.events.config.EventPublicationConfiguration.AsyncPropertiesDefaulter;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncPropertiesDefaulter;
|
||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
@@ -49,7 +49,7 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class EventPublicationConfigurationIntegrationTests {
|
||||
class EventPublicationAutoConfigurationIntegrationTests {
|
||||
|
||||
@Mock EventPublicationRepository repository;
|
||||
|
||||
@@ -137,7 +137,7 @@ class EventPublicationConfigurationIntegrationTests {
|
||||
|
||||
return new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(EventPublicationConfiguration.class, TaskExecutionAutoConfiguration.class))
|
||||
AutoConfigurations.of(EventPublicationAutoConfiguration.class, TaskExecutionAutoConfiguration.class))
|
||||
.withBean(EventPublicationRepository.class, () -> repository);
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ package org.springframework.modulith.events.jdbc;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.jdbc.DatabaseDriver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
|
||||
import org.springframework.modulith.events.config.EventPublicationConfigurationExtension;
|
||||
import org.springframework.modulith.events.core.EventSerializer;
|
||||
|
||||
@@ -32,6 +34,7 @@ import org.springframework.modulith.events.core.EventSerializer;
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore(EventPublicationAutoConfiguration.class)
|
||||
class JdbcEventPublicationAutoConfiguration implements EventPublicationConfigurationExtension {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.jpa;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
|
||||
|
||||
/**
|
||||
* Auto-configuration for JPA based event publication. Registers this class' package as auto-configuration package, so
|
||||
@@ -26,7 +27,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
|
||||
@AutoConfiguration
|
||||
@AutoConfigureBefore({ HibernateJpaAutoConfiguration.class, EventPublicationAutoConfiguration.class })
|
||||
@AutoConfigurationPackage
|
||||
class JpaEventPublicationAutoConfiguration {}
|
||||
class JpaEventPublicationAutoConfiguration extends JpaEventPublicationConfiguration {}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
org.springframework.modulith.events.jpa.JpaEventPublicationAutoConfiguration
|
||||
org.springframework.modulith.events.jpa.JpaEventPublicationConfiguration
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.mongodb;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
|
||||
import org.springframework.modulith.events.config.EventPublicationConfigurationExtension;
|
||||
|
||||
/**
|
||||
@@ -25,7 +27,8 @@ import org.springframework.modulith.events.config.EventPublicationConfigurationE
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfiguration
|
||||
@AutoConfigureBefore(EventPublicationAutoConfiguration.class)
|
||||
class MongoDbEventPublicationAutoConfiguration implements EventPublicationConfigurationExtension {
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user