Skip to content

Commit 967556d

Browse files
committed
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.
1 parent 0b110f7 commit 967556d

File tree

8 files changed

+156
-83
lines changed

8 files changed

+156
-83
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright 2017-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.modulith.events.config;
17+
18+
import java.time.Clock;
19+
import java.time.Duration;
20+
import java.util.Arrays;
21+
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
import org.springframework.beans.BeansException;
25+
import org.springframework.beans.factory.ObjectFactory;
26+
import org.springframework.beans.factory.ObjectProvider;
27+
import org.springframework.beans.factory.config.BeanDefinition;
28+
import org.springframework.beans.factory.config.BeanPostProcessor;
29+
import org.springframework.boot.autoconfigure.AutoConfiguration;
30+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
31+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
32+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
33+
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
34+
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Shutdown;
35+
import org.springframework.context.annotation.Bean;
36+
import org.springframework.context.annotation.Import;
37+
import org.springframework.context.annotation.Role;
38+
import org.springframework.core.env.Environment;
39+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncEnablingConfiguration;
40+
import org.springframework.modulith.events.core.EventPublicationRegistry;
41+
import org.springframework.modulith.events.core.EventPublicationRepository;
42+
import org.springframework.modulith.events.support.CompletionRegisteringAdvisor;
43+
import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
44+
import org.springframework.scheduling.annotation.AbstractAsyncConfiguration;
45+
import org.springframework.scheduling.annotation.EnableAsync;
46+
47+
/**
48+
* Fundamental configuration for the {@link EventPublicationRegistry} support.
49+
*
50+
* @author Oliver Drotbohm
51+
* @author Björn Kieling
52+
* @author Dmitry Belyaev
53+
*/
54+
@AutoConfiguration
55+
@Import(AsyncEnablingConfiguration.class)
56+
public class EventPublicationAutoConfiguration extends EventPublicationConfiguration {
57+
58+
@Override
59+
@Bean
60+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
61+
@ConditionalOnBean(EventPublicationRepository.class)
62+
EventPublicationRegistry eventPublicationRegistry(EventPublicationRepository repository,
63+
ObjectProvider<Clock> clock) {
64+
return super.eventPublicationRegistry(repository, clock);
65+
}
66+
67+
@Bean
68+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
69+
@ConditionalOnBean(EventPublicationRegistry.class)
70+
static PersistentApplicationEventMulticaster applicationEventMulticaster(
71+
ObjectFactory<EventPublicationRegistry> eventPublicationRegistry, ObjectFactory<Environment> environment) {
72+
73+
return EventPublicationConfiguration.applicationEventMulticaster(eventPublicationRegistry, environment);
74+
}
75+
76+
@Bean
77+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
78+
@ConditionalOnBean(EventPublicationRegistry.class)
79+
static CompletionRegisteringAdvisor completionRegisteringAdvisor(ObjectFactory<EventPublicationRegistry> registry) {
80+
return EventPublicationConfiguration.completionRegisteringAdvisor(registry);
81+
}
82+
83+
@Bean
84+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
85+
@ConditionalOnProperty(
86+
name = "spring.modulith.default-async-termination",
87+
havingValue = "true",
88+
matchIfMissing = true)
89+
static AsyncPropertiesDefaulter asyncPropertiesDefaulter(Environment environment) {
90+
return new AsyncPropertiesDefaulter(environment);
91+
}
92+
93+
@EnableAsync
94+
@ConditionalOnMissingBean(AbstractAsyncConfiguration.class)
95+
static class AsyncEnablingConfiguration {}
96+
97+
static class AsyncPropertiesDefaulter implements BeanPostProcessor {
98+
99+
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncPropertiesDefaulter.class);
100+
private static final String PROPERTY = "spring.task.execution.shutdown.await-termination";
101+
102+
private final Environment environment;
103+
104+
AsyncPropertiesDefaulter(Environment environment) {
105+
this.environment = environment;
106+
}
107+
108+
/*
109+
* (non-Javadoc)
110+
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
111+
*/
112+
@Override
113+
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
114+
115+
if (!(bean instanceof TaskExecutionProperties p)) {
116+
return bean;
117+
}
118+
119+
if (anyPropertyConfigured(PROPERTY, PROPERTY + "-period")) {
120+
return bean;
121+
}
122+
123+
LOGGER.debug("Defaulting async shutdown to await termination in 2 seconds.");
124+
125+
Shutdown shutdown = p.getShutdown();
126+
127+
shutdown.setAwaitTermination(true);
128+
shutdown.setAwaitTerminationPeriod(Duration.ofSeconds(2));
129+
130+
return p;
131+
}
132+
133+
private boolean anyPropertyConfigured(String... properties) {
134+
135+
return Arrays.stream(properties)
136+
.anyMatch(it -> environment.containsProperty(it));
137+
}
138+
}
139+
}

spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventPublicationConfiguration.java

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,19 @@
1616
package org.springframework.modulith.events.config;
1717

1818
import java.time.Clock;
19-
import java.time.Duration;
20-
import java.util.Arrays;
2119

22-
import org.slf4j.Logger;
23-
import org.slf4j.LoggerFactory;
24-
import org.springframework.beans.BeansException;
2520
import org.springframework.beans.factory.ObjectFactory;
2621
import org.springframework.beans.factory.ObjectProvider;
2722
import org.springframework.beans.factory.config.BeanDefinition;
28-
import org.springframework.beans.factory.config.BeanPostProcessor;
29-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
30-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
31-
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
32-
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Shutdown;
3323
import org.springframework.context.annotation.Bean;
3424
import org.springframework.context.annotation.Configuration;
35-
import org.springframework.context.annotation.Import;
3625
import org.springframework.context.annotation.Role;
3726
import org.springframework.core.env.Environment;
38-
import org.springframework.modulith.events.config.EventPublicationConfiguration.AsyncEnablingConfiguration;
3927
import org.springframework.modulith.events.core.DefaultEventPublicationRegistry;
4028
import org.springframework.modulith.events.core.EventPublicationRegistry;
4129
import org.springframework.modulith.events.core.EventPublicationRepository;
4230
import org.springframework.modulith.events.support.CompletionRegisteringAdvisor;
4331
import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
44-
import org.springframework.scheduling.annotation.AbstractAsyncConfiguration;
45-
import org.springframework.scheduling.annotation.EnableAsync;
4632

4733
/**
4834
* Fundamental configuration for the {@link EventPublicationRegistry} support.
@@ -52,7 +38,6 @@
5238
* @author Dmitry Belyaev
5339
*/
5440
@Configuration(proxyBeanMethods = false)
55-
@Import(AsyncEnablingConfiguration.class)
5641
class EventPublicationConfiguration {
5742

5843
@Bean
@@ -76,61 +61,4 @@ static PersistentApplicationEventMulticaster applicationEventMulticaster(
7661
static CompletionRegisteringAdvisor completionRegisteringAdvisor(ObjectFactory<EventPublicationRegistry> registry) {
7762
return new CompletionRegisteringAdvisor(registry::getObject);
7863
}
79-
80-
@Bean
81-
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
82-
@ConditionalOnProperty(
83-
name = "spring.modulith.default-async-termination",
84-
havingValue = "true",
85-
matchIfMissing = true)
86-
static AsyncPropertiesDefaulter asyncPropertiesDefaulter(Environment environment) {
87-
return new AsyncPropertiesDefaulter(environment);
88-
}
89-
90-
@EnableAsync
91-
@ConditionalOnMissingBean(AbstractAsyncConfiguration.class)
92-
static class AsyncEnablingConfiguration {}
93-
94-
static class AsyncPropertiesDefaulter implements BeanPostProcessor {
95-
96-
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncPropertiesDefaulter.class);
97-
private static final String PROPERTY = "spring.task.execution.shutdown.await-termination";
98-
99-
private final Environment environment;
100-
101-
AsyncPropertiesDefaulter(Environment environment) {
102-
this.environment = environment;
103-
}
104-
105-
/*
106-
* (non-Javadoc)
107-
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
108-
*/
109-
@Override
110-
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
111-
112-
if (!(bean instanceof TaskExecutionProperties p)) {
113-
return bean;
114-
}
115-
116-
if (anyPropertyConfigured(PROPERTY, PROPERTY + "-period")) {
117-
return bean;
118-
}
119-
120-
LOGGER.debug("Defaulting async shutdown to await termination in 2 seconds.");
121-
122-
Shutdown shutdown = p.getShutdown();
123-
124-
shutdown.setAwaitTermination(true);
125-
shutdown.setAwaitTerminationPeriod(Duration.ofSeconds(2));
126-
127-
return p;
128-
}
129-
130-
private boolean anyPropertyConfigured(String... properties) {
131-
132-
return Arrays.stream(properties)
133-
.anyMatch(it -> environment.containsProperty(it));
134-
}
135-
}
13664
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
org.springframework.modulith.events.config.EventPublicationConfiguration
1+
org.springframework.modulith.events.config.EventPublicationAutoConfiguration
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3636
import org.springframework.boot.test.context.runner.ContextConsumer;
3737
import org.springframework.context.annotation.AdviceMode;
38-
import org.springframework.modulith.events.config.EventPublicationConfiguration.AsyncPropertiesDefaulter;
38+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncPropertiesDefaulter;
3939
import org.springframework.modulith.events.core.EventPublicationRegistry;
4040
import org.springframework.modulith.events.core.EventPublicationRepository;
4141
import org.springframework.scheduling.annotation.EnableAsync;
@@ -49,7 +49,7 @@
4949
* @author Oliver Drotbohm
5050
*/
5151
@ExtendWith(MockitoExtension.class)
52-
class EventPublicationConfigurationIntegrationTests {
52+
class EventPublicationAutoConfigurationIntegrationTests {
5353

5454
@Mock EventPublicationRepository repository;
5555

@@ -137,7 +137,7 @@ private ApplicationContextRunner basicSetup() {
137137

138138
return new ApplicationContextRunner()
139139
.withConfiguration(
140-
AutoConfigurations.of(EventPublicationConfiguration.class, TaskExecutionAutoConfiguration.class))
140+
AutoConfigurations.of(EventPublicationAutoConfiguration.class, TaskExecutionAutoConfiguration.class))
141141
.withBean(EventPublicationRepository.class, () -> repository);
142142
}
143143

spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
import javax.sql.DataSource;
1919

20+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2021
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2122
import org.springframework.boot.jdbc.DatabaseDriver;
2223
import org.springframework.context.annotation.Bean;
2324
import org.springframework.context.annotation.Configuration;
2425
import org.springframework.core.io.ResourceLoader;
2526
import org.springframework.jdbc.core.JdbcTemplate;
27+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
2628
import org.springframework.modulith.events.config.EventPublicationConfigurationExtension;
2729
import org.springframework.modulith.events.core.EventSerializer;
2830

@@ -32,6 +34,7 @@
3234
* @author Oliver Drotbohm
3335
*/
3436
@Configuration(proxyBeanMethods = false)
37+
@AutoConfigureBefore(EventPublicationAutoConfiguration.class)
3538
class JdbcEventPublicationAutoConfiguration implements EventPublicationConfigurationExtension {
3639

3740
@Bean

spring-modulith-events/spring-modulith-events-jpa/src/main/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfiguration.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515
*/
1616
package org.springframework.modulith.events.jpa;
1717

18+
import org.springframework.boot.autoconfigure.AutoConfiguration;
1819
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
1920
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2021
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
21-
import org.springframework.context.annotation.Configuration;
22+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
2223

2324
/**
2425
* Auto-configuration for JPA based event publication. Registers this class' package as auto-configuration package, so
2526
* that it gets picked up for entity scanning by default.
2627
*
2728
* @author Oliver Drotbohm
2829
*/
29-
@Configuration(proxyBeanMethods = false)
30-
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
30+
@AutoConfiguration
31+
@AutoConfigureBefore({ HibernateJpaAutoConfiguration.class, EventPublicationAutoConfiguration.class })
3132
@AutoConfigurationPackage
32-
class JpaEventPublicationAutoConfiguration {}
33+
class JpaEventPublicationAutoConfiguration extends JpaEventPublicationConfiguration {}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
org.springframework.modulith.events.jpa.JpaEventPublicationAutoConfiguration
2-
org.springframework.modulith.events.jpa.JpaEventPublicationConfiguration

spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationAutoConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,20 @@
1515
*/
1616
package org.springframework.modulith.events.mongodb;
1717

18+
import org.springframework.boot.autoconfigure.AutoConfiguration;
19+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
1820
import org.springframework.context.annotation.Bean;
19-
import org.springframework.context.annotation.Configuration;
2021
import org.springframework.data.mongodb.core.MongoTemplate;
22+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
2123
import org.springframework.modulith.events.config.EventPublicationConfigurationExtension;
2224

2325
/**
2426
* Autoconfiguration for MongoDB event publication repository.
2527
*
2628
* @author Oliver Drotbohm
2729
*/
28-
@Configuration(proxyBeanMethods = false)
30+
@AutoConfiguration
31+
@AutoConfigureBefore(EventPublicationAutoConfiguration.class)
2932
class MongoDbEventPublicationAutoConfiguration implements EventPublicationConfigurationExtension {
3033

3134
@Bean

0 commit comments

Comments
 (0)