Browse Source

Retrieve `Environment` from `RegisteredBean`.

Closes #3414
Original pull request: #3415
pull/3426/head
Christoph Strobl 3 weeks ago committed by Mark Paluch
parent
commit
1aa3b06a3e
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 26
      src/main/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessor.java
  2. 40
      src/test/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessorUnitTests.java

26
src/main/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessor.java

@ -33,6 +33,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.EnvironmentAware; import org.springframework.context.EnvironmentAware;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.data.domain.ManagedTypes; import org.springframework.data.domain.ManagedTypes;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
@ -40,6 +41,7 @@ import org.springframework.data.util.TypeCollector;
import org.springframework.data.util.TypeContributor; import org.springframework.data.util.TypeContributor;
import org.springframework.data.util.TypeUtils; import org.springframework.data.util.TypeUtils;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -54,7 +56,8 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
private final Log logger = LogFactory.getLog(getClass()); private final Log logger = LogFactory.getLog(getClass());
private @Nullable String moduleIdentifier; private @Nullable String moduleIdentifier;
private Lazy<Environment> environment = Lazy.of(StandardEnvironment::new); private static final Lazy<Environment> DEFAULT_ENVIRONMENT = Lazy.of(StandardEnvironment::new);
private @Nullable Environment environment = null;
public void setModuleIdentifier(@Nullable String moduleIdentifier) { public void setModuleIdentifier(@Nullable String moduleIdentifier) {
this.moduleIdentifier = moduleIdentifier; this.moduleIdentifier = moduleIdentifier;
@ -67,7 +70,7 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
@Override @Override
public void setEnvironment(Environment environment) { public void setEnvironment(Environment environment) {
this.environment = Lazy.of(environment); this.environment = environment;
} }
@Override @Override
@ -77,7 +80,7 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
return null; return null;
} }
DefaultAotContext aotContext = new DefaultAotContext(registeredBean.getBeanFactory(), environment.get()); DefaultAotContext aotContext = new DefaultAotContext(registeredBean.getBeanFactory(), getConfiguredEnvironmentOrTryToResolveOne(registeredBean));
return contribute(aotContext, resolveManagedTypes(registeredBean), registeredBean); return contribute(aotContext, resolveManagedTypes(registeredBean), registeredBean);
} }
@ -183,4 +186,21 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
protected boolean matchesPrefix(@Nullable String beanName) { protected boolean matchesPrefix(@Nullable String beanName) {
return StringUtils.startsWithIgnoreCase(beanName, getModuleIdentifier()); return StringUtils.startsWithIgnoreCase(beanName, getModuleIdentifier());
} }
protected Environment getConfiguredEnvironmentOrTryToResolveOne(RegisteredBean registeredBean) {
if (this.environment != null) {
return this.environment;
}
if (registeredBean.getBeanFactory() instanceof EnvironmentCapable ec) {
return ec.getEnvironment();
} else {
String[] beanNamesForType = registeredBean.getBeanFactory().getBeanNamesForType(Environment.class);
if (!ObjectUtils.isEmpty(beanNamesForType)) {
return registeredBean.getBeanFactory().getBean(beanNamesForType[0], Environment.class);
}
}
return DEFAULT_ENVIRONMENT.get();
}
} }

40
src/test/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessorUnitTests.java

@ -41,10 +41,12 @@ import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.aot.ManagedTypesRegistrationAotContribution.ManagedTypesInstanceCodeFragment; import org.springframework.data.aot.ManagedTypesRegistrationAotContribution.ManagedTypesInstanceCodeFragment;
import org.springframework.data.domain.ManagedTypes; import org.springframework.data.domain.ManagedTypes;
import org.springframework.javapoet.MethodSpec; import org.springframework.javapoet.MethodSpec;
import org.springframework.javapoet.MethodSpec.Builder; import org.springframework.javapoet.MethodSpec.Builder;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
/** /**
@ -198,7 +200,8 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
@Test // GH-2680 @Test // GH-2680
void generatesInstanceSupplierCodeFragmentToAvoidDuplicateInvocationsForEmptyManagedTypes() { void generatesInstanceSupplierCodeFragmentToAvoidDuplicateInvocationsForEmptyManagedTypes() {
beanFactory.registerBeanDefinition("commons.managed-types", BeanDefinitionBuilder.rootBeanDefinition(EmptyManagedTypes.class).getBeanDefinition()); beanFactory.registerBeanDefinition("commons.managed-types",
BeanDefinitionBuilder.rootBeanDefinition(EmptyManagedTypes.class).getBeanDefinition());
RegisteredBean registeredBean = RegisteredBean.of(beanFactory, "commons.managed-types"); RegisteredBean registeredBean = RegisteredBean.of(beanFactory, "commons.managed-types");
BeanRegistrationAotContribution contribution = createPostProcessor("commons") BeanRegistrationAotContribution contribution = createPostProcessor("commons")
@ -206,7 +209,6 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
AotTestCodeContributionBuilder.withContextFor(this.getClass()).writeContentFor(contribution).compile(it -> { AotTestCodeContributionBuilder.withContextFor(this.getClass()).writeContentFor(contribution).compile(it -> {
InstanceSupplier<ManagedTypes> types = ReflectionTestUtils InstanceSupplier<ManagedTypes> types = ReflectionTestUtils
.invokeMethod(it.getAllCompiledClasses().iterator().next(), "instance"); .invokeMethod(it.getAllCompiledClasses().iterator().next(), "instance");
try { try {
@ -266,6 +268,40 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
assertThat(fragment.canGenerateCode()).isFalse(); assertThat(fragment.canGenerateCode()).isFalse();
} }
@Test // GH-3414
void usesConfiguredEnvironment() {
MockEnvironment env = spy(new MockEnvironment());
ManagedTypesBeanRegistrationAotProcessor processor = createPostProcessor("commons");
processor.setEnvironment(env);
beanFactory.registerBeanDefinition("commons.managed-types", managedTypesDefinition);
BeanRegistrationAotContribution contribution = processor
.processAheadOfTime(RegisteredBean.of(beanFactory, "commons.managed-types"));
contribution.applyTo(new TestGenerationContext(Object.class), null);
verify(env).getProperty(eq("spring.aot.data.accessors.enabled"), eq(Boolean.class), eq(true));
}
@Test // GH-3414
void usesUsesEnvironmentFromBeanIfNotSet() {
MockEnvironment env = spy(new MockEnvironment());
ManagedTypesBeanRegistrationAotProcessor processor = createPostProcessor("commons");
beanFactory.registerBeanDefinition("commons.managed-types", managedTypesDefinition);
beanFactory.registerBeanDefinition("environment", new RootBeanDefinition(Environment.class, () -> env));
BeanRegistrationAotContribution contribution = processor
.processAheadOfTime(RegisteredBean.of(beanFactory, "commons.managed-types"));
contribution.applyTo(new TestGenerationContext(Object.class), null);
verify(env).getProperty(eq("spring.aot.data.accessors.enabled"), eq(Boolean.class), eq(true));
}
private ManagedTypesBeanRegistrationAotProcessor createPostProcessor(String moduleIdentifier) { private ManagedTypesBeanRegistrationAotProcessor createPostProcessor(String moduleIdentifier) {
ManagedTypesBeanRegistrationAotProcessor postProcessor = new ManagedTypesBeanRegistrationAotProcessor(); ManagedTypesBeanRegistrationAotProcessor postProcessor = new ManagedTypesBeanRegistrationAotProcessor();
postProcessor.setModuleIdentifier(moduleIdentifier); postProcessor.setModuleIdentifier(moduleIdentifier);

Loading…
Cancel
Save