@@ -56,8 +56,8 @@ import org.springframework.beans.factory.annotation.InjectionMetadata.InjectedEl
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.generator.BeanInstanceAotPostProcessor;
|
||||
import org.springframework.beans.factory.generator.BeanInstanceContributor;
|
||||
import org.springframework.beans.factory.generator.AotContributingBeanPostProcessor;
|
||||
import org.springframework.beans.factory.generator.BeanInstantiationContributor;
|
||||
import org.springframework.beans.factory.generator.InjectionGenerator;
|
||||
import org.springframework.beans.factory.support.LookupOverride;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
@@ -140,7 +140,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see Value
|
||||
*/
|
||||
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
|
||||
MergedBeanDefinitionPostProcessor, BeanInstanceAotPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
MergedBeanDefinitionPostProcessor, AotContributingBeanPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -268,12 +268,12 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
public BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, beanDefinition);
|
||||
Collection<InjectedElement> injectedElements = metadata.getInjectedElements();
|
||||
return (!ObjectUtils.isEmpty(injectedElements)
|
||||
? new AutowiredAnnotationBeanInstanceContributor(injectedElements)
|
||||
: BeanInstanceContributor.NO_OP);
|
||||
? new AutowiredAnnotationBeanInstantiationContributor(injectedElements)
|
||||
: BeanInstantiationContributor.NO_OP);
|
||||
}
|
||||
|
||||
private InjectionMetadata findInjectionMetadata(String beanName, Class<?> beanType, RootBeanDefinition beanDefinition) {
|
||||
@@ -821,13 +821,13 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
}
|
||||
}
|
||||
|
||||
private static final class AutowiredAnnotationBeanInstanceContributor implements BeanInstanceContributor {
|
||||
private static final class AutowiredAnnotationBeanInstantiationContributor implements BeanInstantiationContributor {
|
||||
|
||||
private final Collection<InjectedElement> injectedElements;
|
||||
|
||||
private final InjectionGenerator generator;
|
||||
|
||||
AutowiredAnnotationBeanInstanceContributor(Collection<InjectedElement> injectedElements) {
|
||||
AutowiredAnnotationBeanInstantiationContributor(Collection<InjectedElement> injectedElements) {
|
||||
this.injectedElements = injectedElements;
|
||||
this.generator = new InjectionGenerator();
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
||||
/**
|
||||
* Strategy interface to be implemented by a {@link BeanPostProcessor} that
|
||||
* participates in a bean instance setup and can provide an equivalent setup
|
||||
* using generated code.
|
||||
* Specialization of {@link BeanPostProcessor} that contributes to bean
|
||||
* instantiation ahead of time, providing generated code that is equivalent to
|
||||
* its runtime behavior.
|
||||
*
|
||||
* <p>Contrary to other bean post processors, implementations of this interface
|
||||
* are instantiated at build-time and should not rely on other beans in the
|
||||
@@ -32,15 +32,15 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
* @since 6.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BeanInstanceAotPostProcessor extends BeanPostProcessor {
|
||||
public interface AotContributingBeanPostProcessor extends BeanPostProcessor {
|
||||
|
||||
/**
|
||||
* Build a {@link BeanInstanceContributor} for the given bean definition.
|
||||
* Build a {@link BeanInstantiationContributor} for the given bean definition.
|
||||
* @param beanDefinition the merged bean definition for the bean
|
||||
* @param beanType the actual type of the managed bean instance
|
||||
* @param beanType the inferred type of the bean
|
||||
* @param beanName the name of the bean
|
||||
* @return the contributor to use
|
||||
*/
|
||||
BeanInstanceContributor buildAotContributor(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
|
||||
BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
|
||||
|
||||
}
|
||||
@@ -19,21 +19,20 @@ package org.springframework.beans.factory.generator;
|
||||
import org.springframework.aot.generator.CodeContribution;
|
||||
|
||||
/**
|
||||
* Strategy interface to be implemented by components that participates in a
|
||||
* bean instance setup so that the generated code provides an equivalent
|
||||
* setup.
|
||||
* Contributor to the code that instantiates a bean following ahead of time
|
||||
* processing.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BeanInstanceContributor {
|
||||
public interface BeanInstantiationContributor {
|
||||
|
||||
/**
|
||||
* A {@link BeanInstanceContributor} that does not contribute anything
|
||||
* A {@link BeanInstantiationContributor} that does not contribute anything
|
||||
* to the {@link CodeContribution}.
|
||||
*/
|
||||
BeanInstanceContributor NO_OP = contribution -> { };
|
||||
BeanInstantiationContributor NO_OP = contribution -> { };
|
||||
|
||||
/**
|
||||
* Contribute to the specified {@link CodeContribution}.
|
||||
@@ -36,19 +36,20 @@ import org.springframework.util.ClassUtils;
|
||||
* Write the necessary statements to instantiate a bean.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @see BeanInstantiationContributor
|
||||
*/
|
||||
class DefaultBeanInstanceGenerator {
|
||||
class DefaultBeanInstantiationGenerator {
|
||||
|
||||
private final Executable instanceCreator;
|
||||
|
||||
private final List<BeanInstanceContributor> contributors;
|
||||
private final List<BeanInstantiationContributor> contributors;
|
||||
|
||||
private final InjectionGenerator injectionGenerator;
|
||||
|
||||
private final Options beanInstanceOptions;
|
||||
|
||||
|
||||
DefaultBeanInstanceGenerator(Executable instanceCreator, List<BeanInstanceContributor> contributors) {
|
||||
DefaultBeanInstantiationGenerator(Executable instanceCreator, List<BeanInstantiationContributor> contributors) {
|
||||
this.instanceCreator = instanceCreator;
|
||||
this.contributors = List.copyOf(contributors);
|
||||
this.injectionGenerator = new InjectionGenerator();
|
||||
@@ -62,7 +63,7 @@ class DefaultBeanInstanceGenerator {
|
||||
* @param runtimeHints the runtime hints instance to use
|
||||
* @return a code contribution that provides an initialized bean instance
|
||||
*/
|
||||
public CodeContribution generateBeanInstance(RuntimeHints runtimeHints) {
|
||||
public CodeContribution generateBeanInstantiation(RuntimeHints runtimeHints) {
|
||||
DefaultCodeContribution contribution = new DefaultCodeContribution(runtimeHints);
|
||||
contribution.protectedAccess().analyze(this.instanceCreator, this.beanInstanceOptions);
|
||||
if (this.instanceCreator instanceof Constructor<?> constructor) {
|
||||
@@ -109,7 +110,7 @@ class DefaultBeanInstanceGenerator {
|
||||
contribution.statements().addStatement(code.build());
|
||||
|
||||
if (multiStatements) {
|
||||
for (BeanInstanceContributor contributor : this.contributors) {
|
||||
for (BeanInstantiationContributor contributor : this.contributors) {
|
||||
contributor.contribute(contribution);
|
||||
}
|
||||
contribution.statements().addStatement("return bean")
|
||||
@@ -147,7 +148,7 @@ class DefaultBeanInstanceGenerator {
|
||||
code.add(this.injectionGenerator.writeInstantiation(method));
|
||||
contribution.statements().addStatement(code.build());
|
||||
if (multiStatements) {
|
||||
for (BeanInstanceContributor contributor : this.contributors) {
|
||||
for (BeanInstantiationContributor contributor : this.contributors) {
|
||||
contributor.contribute(contribution);
|
||||
}
|
||||
contribution.statements().addStatement("return bean")
|
||||
@@ -24,7 +24,7 @@ import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessorTests.ResourceInjectionBean;
|
||||
import org.springframework.beans.factory.generator.BeanInstanceContributor;
|
||||
import org.springframework.beans.factory.generator.BeanInstantiationContributor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.env.Environment;
|
||||
@@ -37,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class AutowiredAnnotationBeanInstanceContributorTests {
|
||||
class AutowiredAnnotationBeanInstantiationContributorTests {
|
||||
|
||||
@Test
|
||||
void buildAotContributorWithPackageProtectedFieldInjection() {
|
||||
@@ -63,7 +63,7 @@ class AutowiredAnnotationBeanInstanceContributorTests {
|
||||
assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo("""
|
||||
instanceContext.field("environment", Environment.class)
|
||||
.invoke(beanFactory, (attributes) -> {
|
||||
Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstanceContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class);
|
||||
Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstantiationContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class);
|
||||
ReflectionUtils.makeAccessible(environmentField);
|
||||
ReflectionUtils.setField(environmentField, bean, attributes.get(0));
|
||||
})""");
|
||||
@@ -117,19 +117,19 @@ class AutowiredAnnotationBeanInstanceContributorTests {
|
||||
|
||||
@Test
|
||||
void buildAotContributorWithoutInjectionPoints() {
|
||||
BeanInstanceContributor contributor = createAotContributor(String.class);
|
||||
assertThat(contributor).isNotNull().isSameAs(BeanInstanceContributor.NO_OP);
|
||||
BeanInstantiationContributor contributor = createAotContributor(String.class);
|
||||
assertThat(contributor).isNotNull().isSameAs(BeanInstantiationContributor.NO_OP);
|
||||
}
|
||||
|
||||
private DefaultCodeContribution contribute(Class<?> type) {
|
||||
BeanInstanceContributor contributor = createAotContributor(type);
|
||||
BeanInstantiationContributor contributor = createAotContributor(type);
|
||||
assertThat(contributor).isNotNull();
|
||||
DefaultCodeContribution contribution = new DefaultCodeContribution(new RuntimeHints());
|
||||
contributor.contribute(contribution);
|
||||
return contribution;
|
||||
}
|
||||
|
||||
private BeanInstanceContributor createAotContributor(Class<?> type) {
|
||||
private BeanInstantiationContributor createAotContributor(Class<?> type) {
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(type);
|
||||
return bpp.buildAotContributor(beanDefinition, type, "test");
|
||||
@@ -48,11 +48,11 @@ import org.springframework.util.ReflectionUtils;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultBeanInstanceGenerator}.
|
||||
* Tests for {@link DefaultBeanInstantiationGenerator}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class DefaultBeanInstanceGeneratorTests {
|
||||
class DefaultBeanInstantiationGeneratorTests {
|
||||
|
||||
@Test
|
||||
void generateUsingDefaultConstructorUsesMethodReference() {
|
||||
@@ -109,7 +109,7 @@ class DefaultBeanInstanceGeneratorTests {
|
||||
void generateUsingNoArgConstructorAndContributorsDoesNotUseMethodReference() {
|
||||
CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0],
|
||||
contrib -> contrib.statements().add(CodeBlock.of("// hello\n")),
|
||||
BeanInstanceContributor.NO_OP);
|
||||
BeanInstantiationContributor.NO_OP);
|
||||
assertThat(code(contribution)).isEqualTo("""
|
||||
(instanceContext) -> {
|
||||
SimpleConfiguration bean = new SimpleConfiguration();
|
||||
@@ -240,10 +240,10 @@ class DefaultBeanInstanceGeneratorTests {
|
||||
}
|
||||
|
||||
private CodeContribution generate(Executable executable,
|
||||
BeanInstanceContributor... beanInstanceContributors) {
|
||||
DefaultBeanInstanceGenerator generator = new DefaultBeanInstanceGenerator(executable,
|
||||
Arrays.asList(beanInstanceContributors));
|
||||
return generator.generateBeanInstance(new RuntimeHints());
|
||||
BeanInstantiationContributor... beanInstantiationContributors) {
|
||||
DefaultBeanInstantiationGenerator generator = new DefaultBeanInstantiationGenerator(executable,
|
||||
Arrays.asList(beanInstantiationContributors));
|
||||
return generator.generateBeanInstantiation(new RuntimeHints());
|
||||
}
|
||||
|
||||
private static Method method(Class<?> type, String methodName, Class<?>... parameterTypes) {
|
||||
Reference in New Issue
Block a user