Browse Source

Partially revert auditing bean registration changes.

Restoring bean registration while keeping the optional nature of AuditorAware in the Reactive-/AuditingHandler.

The changes done previously caused AOT code generation to fail with:
org.springframework.aot.generate.UnsupportedTypeValueCodeGenerationException: Code generation does not support org.springframework.beans.factory.config.AutowiredPropertyMarker

See: #3177
pull/3394/head
Christoph Strobl 2 months ago
parent
commit
d8718b46b7
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 5
      src/main/antora/modules/ROOT/pages/auditing.adoc
  2. 8
      src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.java
  3. 51
      src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java

5
src/main/antora/modules/ROOT/pages/auditing.adoc

@ -3,16 +3,13 @@
[[auditing.basics]] [[auditing.basics]]
== Basics == Basics
Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened.To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface.
Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened.
To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface.
Additionally, auditing has to be enabled either through Annotation configuration or XML configuration to register the required infrastructure components. Additionally, auditing has to be enabled either through Annotation configuration or XML configuration to register the required infrastructure components.
Please refer to the store-specific section for configuration samples. Please refer to the store-specific section for configuration samples.
[NOTE] [NOTE]
==== ====
Applications that only track creation and modification dates are not required do make their entities implement <<auditing.auditor-aware,`AuditorAware`>>. Applications that only track creation and modification dates are not required do make their entities implement <<auditing.auditor-aware,`AuditorAware`>>.
If no `AuditorAware` or `DateTimeProvider` bean is configured, `AuditingHandler` will use Spring's autowiring to detect a matching bean if beans of the corresponding type are available in the application context.
==== ====
[[auditing.annotations]] [[auditing.annotations]]

8
src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.java

@ -116,13 +116,12 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AuditingConfiguration configuration, protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AuditingConfiguration configuration,
BeanDefinitionBuilder builder) { BeanDefinitionBuilder builder) {
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
if (StringUtils.hasText(configuration.getAuditorAwareRef())) { if (StringUtils.hasText(configuration.getAuditorAwareRef())) {
builder.addPropertyValue(AUDITOR_AWARE, builder.addPropertyValue(AUDITOR_AWARE,
createLazyInitTargetSourceBeanDefinition(configuration.getAuditorAwareRef())); createLazyInitTargetSourceBeanDefinition(configuration.getAuditorAwareRef()));
} }
else {
builder.addAutowiredProperty(AUDITOR_AWARE);
}
builder.addPropertyValue(SET_DATES, configuration.isSetDates()); builder.addPropertyValue(SET_DATES, configuration.isSetDates());
builder.addPropertyValue(MODIFY_ON_CREATE, configuration.isModifyOnCreate()); builder.addPropertyValue(MODIFY_ON_CREATE, configuration.isModifyOnCreate());
@ -130,9 +129,6 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe
if (StringUtils.hasText(configuration.getDateTimeProviderRef())) { if (StringUtils.hasText(configuration.getDateTimeProviderRef())) {
builder.addPropertyReference(DATE_TIME_PROVIDER, configuration.getDateTimeProviderRef()); builder.addPropertyReference(DATE_TIME_PROVIDER, configuration.getDateTimeProviderRef());
} }
else {
builder.addAutowiredProperty(DATE_TIME_PROVIDER);
}
builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE); builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);

51
src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java

@ -20,23 +20,19 @@ import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.util.Optional;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.config.AutowiredPropertyMarker;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.auditing.EnableAuditing; import org.springframework.data.auditing.EnableAuditing;
import org.springframework.data.mapping.context.PersistentEntities;
/** /**
* Unit tests for {@link AuditingBeanDefinitionRegistrarSupport}. * Unit tests for {@link AuditingBeanDefinitionRegistrarSupport}.
@ -46,7 +42,6 @@ import org.springframework.data.mapping.context.PersistentEntities;
* @author Oliver Gierke * @author Oliver Gierke
* @author Francisco Soler * @author Francisco Soler
* @author Jaeyeon Kim * @author Jaeyeon Kim
* @author Mark Paluch
*/ */
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class AuditingBeanDefinitionRegistrarSupportUnitTests { class AuditingBeanDefinitionRegistrarSupportUnitTests {
@ -82,28 +77,13 @@ class AuditingBeanDefinitionRegistrarSupportUnitTests {
.isThrownBy(() -> registrar.registerBeanDefinitions(metadata, null)); .isThrownBy(() -> registrar.registerBeanDefinitions(metadata, null));
} }
@Test // GH-3177 @Test // DATACMNS-3177
void setsAuditorAwareAndDateTimeProviderIfConfigured() { void setsAuditorAwareAndDateTimeProviderIfConfigured() {
AuditingConfiguration configuration = new DummyAuditingBeanDefinitionRegistrarSupport().getConfiguration(null);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingHandler.class);
DummyAuditingBeanDefinitionRegistrarSupport registrar = new DummyAuditingBeanDefinitionRegistrarSupport();
BeanDefinitionBuilder result = registrar.configureDefaultAuditHandlerAttributes(configuration, builder);
AbstractBeanDefinition beanDefinition = result.getBeanDefinition();
assertThat(beanDefinition.getPropertyValues().contains("auditorAware")).isTrue();
assertThat(beanDefinition.getPropertyValues().contains("dateTimeProvider")).isTrue();
}
@Test // GH-3177
void doesNotSetAuditorAwareAndDateTimeProviderIfNotConfigured() {
AuditingConfiguration configuration = new AuditingConfiguration() { AuditingConfiguration configuration = new AuditingConfiguration() {
@Override @Override
public String getAuditorAwareRef() { public String getAuditorAwareRef() {
return ""; return "auditorAwareBean";
} }
@Override @Override
@ -113,7 +93,7 @@ class AuditingBeanDefinitionRegistrarSupportUnitTests {
@Override @Override
public String getDateTimeProviderRef() { public String getDateTimeProviderRef() {
return ""; return "dateTimeProviderBean";
} }
@Override @Override
@ -128,12 +108,13 @@ class AuditingBeanDefinitionRegistrarSupportUnitTests {
BeanDefinitionBuilder result = registrar.configureDefaultAuditHandlerAttributes(configuration, builder); BeanDefinitionBuilder result = registrar.configureDefaultAuditHandlerAttributes(configuration, builder);
AbstractBeanDefinition beanDefinition = result.getBeanDefinition(); AbstractBeanDefinition beanDefinition = result.getBeanDefinition();
assertThat(beanDefinition.getPropertyValues().get("auditorAware")).isEqualTo(AutowiredPropertyMarker.INSTANCE); assertThat(beanDefinition.getAutowireMode()).isEqualTo(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
assertThat(beanDefinition.getPropertyValues().get("dateTimeProvider")).isEqualTo(AutowiredPropertyMarker.INSTANCE); assertThat(beanDefinition.getPropertyValues().contains("auditorAware")).isTrue();
assertThat(beanDefinition.getPropertyValues().contains("dateTimeProvider")).isTrue();
} }
@Test // GH-3177 @Test // DATACMNS-3177
void optionalAutowiringShouldConsiderOptionalProperties() { void doesNotSetAuditorAwareAndDateTimeProviderIfNotConfigured() {
AuditingConfiguration configuration = new AuditingConfiguration() { AuditingConfiguration configuration = new AuditingConfiguration() {
@Override @Override
@ -152,24 +133,18 @@ class AuditingBeanDefinitionRegistrarSupportUnitTests {
} }
@Override @Override
public boolean isModifyOnCreate() { public boolean isModifyOnCreate() { return true; }
return true;
}
}; };
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingHandler.class); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingHandler.class);
builder.addConstructorArgValue(PersistentEntities.of());
DummyAuditingBeanDefinitionRegistrarSupport registrar = new DummyAuditingBeanDefinitionRegistrarSupport(); DummyAuditingBeanDefinitionRegistrarSupport registrar = new DummyAuditingBeanDefinitionRegistrarSupport();
BeanDefinitionBuilder result = registrar.configureDefaultAuditHandlerAttributes(configuration, builder); BeanDefinitionBuilder result = registrar.configureDefaultAuditHandlerAttributes(configuration, builder);
AbstractBeanDefinition beanDefinition = result.getBeanDefinition();
GenericApplicationContext context = new GenericApplicationContext(); assertThat(beanDefinition.getAutowireMode()).isEqualTo(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
context.registerBeanDefinition("auditingHandler", result.getBeanDefinition()); assertThat(beanDefinition.getPropertyValues().contains("auditorAware")).isFalse();
context.refresh(); assertThat(beanDefinition.getPropertyValues().contains("dateTimeProvider")).isFalse();
AuditingHandler handler = context.getBean(AuditingHandler.class);
assertThat(handler).extracting("auditorAware").isEqualTo(Optional.empty());
} }
static class SampleConfig {} static class SampleConfig {}

Loading…
Cancel
Save