Merge branch '6.2.x'
# Conflicts: # spring-context/src/main/java/org/springframework/context/aot/BeanFactoryInitializationAotContributions.java # spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java # spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateQueryException.java
This commit is contained in:
commit
90c875144a
|
@ -53,6 +53,9 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueH
|
|||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.InstanceSupplier;
|
||||
import org.springframework.beans.factory.support.LookupOverride;
|
||||
import org.springframework.beans.factory.support.MethodOverride;
|
||||
import org.springframework.beans.factory.support.ReplaceOverride;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.javapoet.CodeBlock;
|
||||
import org.springframework.javapoet.CodeBlock.Builder;
|
||||
|
@ -145,6 +148,7 @@ class BeanDefinitionPropertiesCodeGenerator {
|
|||
addPropertyValues(code, beanDefinition);
|
||||
addAttributes(code, beanDefinition);
|
||||
addQualifiers(code, beanDefinition);
|
||||
addMethodOverrides(code, beanDefinition);
|
||||
return code.build();
|
||||
}
|
||||
|
||||
|
@ -274,6 +278,36 @@ class BeanDefinitionPropertiesCodeGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private void addMethodOverrides(CodeBlock.Builder code, RootBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.hasMethodOverrides()) {
|
||||
for (MethodOverride methodOverride : beanDefinition.getMethodOverrides().getOverrides()) {
|
||||
if (methodOverride instanceof LookupOverride lookupOverride) {
|
||||
Collection<CodeBlock> arguments = new ArrayList<>();
|
||||
arguments.add(CodeBlock.of("$S", lookupOverride.getMethodName()));
|
||||
arguments.add(CodeBlock.of("$S", lookupOverride.getBeanName()));
|
||||
code.addStatement("$L.getMethodOverrides().addOverride(new $T($L))", BEAN_DEFINITION_VARIABLE,
|
||||
LookupOverride.class, CodeBlock.join(arguments, ", "));
|
||||
}
|
||||
else if (methodOverride instanceof ReplaceOverride replaceOverride) {
|
||||
Collection<CodeBlock> arguments = new ArrayList<>();
|
||||
arguments.add(CodeBlock.of("$S", replaceOverride.getMethodName()));
|
||||
arguments.add(CodeBlock.of("$S", replaceOverride.getMethodReplacerBeanName()));
|
||||
List<String> typeIdentifiers = replaceOverride.getTypeIdentifiers();
|
||||
if (!typeIdentifiers.isEmpty()) {
|
||||
arguments.add(CodeBlock.of("java.util.List.of($S)",
|
||||
StringUtils.collectionToDelimitedString(typeIdentifiers, ", ")));
|
||||
}
|
||||
code.addStatement("$L.getMethodOverrides().addOverride(new $T($L))", BEAN_DEFINITION_VARIABLE,
|
||||
ReplaceOverride.class, CodeBlock.join(arguments, ", "));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
|
||||
methodOverride.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CodeBlock generateValue(@Nullable String name, @Nullable Object value) {
|
||||
PropertyNamesStack.push(name);
|
||||
try {
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueH
|
|||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionValueResolver;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.InstanceSupplier;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
@ -343,6 +344,11 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
|||
|
||||
private Object instantiate(RegisteredBean registeredBean, Executable executable, @Nullable Object[] args) {
|
||||
if (executable instanceof Constructor<?> constructor) {
|
||||
if (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf &&
|
||||
registeredBean.getMergedBeanDefinition().hasMethodOverrides()) {
|
||||
return dlbf.getInstantiationStrategy().instantiate(registeredBean.getMergedBeanDefinition(),
|
||||
registeredBean.getBeanName(), registeredBean.getBeanFactory());
|
||||
}
|
||||
return BeanUtils.instantiateClass(constructor, args);
|
||||
}
|
||||
if (executable instanceof Method method) {
|
||||
|
|
|
@ -41,8 +41,7 @@ public interface BeanRegistrationAotContribution {
|
|||
* default code generation isn't suitable.
|
||||
* @param generationContext the generation context
|
||||
* @param codeFragments the existing code fragments
|
||||
* @return the code fragments to use, may be the original instance or a
|
||||
* wrapper
|
||||
* @return the code fragments to use, may be the original instance or a wrapper
|
||||
*/
|
||||
default BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(
|
||||
GenerationContext generationContext, BeanRegistrationCodeFragments codeFragments) {
|
||||
|
@ -78,8 +77,7 @@ public interface BeanRegistrationAotContribution {
|
|||
return defaultCodeFragments.apply(codeFragments);
|
||||
}
|
||||
@Override
|
||||
public void applyTo(GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode) {
|
||||
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,14 +31,15 @@ import org.springframework.javapoet.CodeBlock;
|
|||
|
||||
/**
|
||||
* Generate the various fragments of code needed to register a bean.
|
||||
* <p>
|
||||
* A default implementation is provided that suits most needs and custom code
|
||||
*
|
||||
* <p>A default implementation is provided that suits most needs and custom code
|
||||
* fragments are only expected to be used by library authors having built custom
|
||||
* arrangement on top of the core container.
|
||||
* <p>
|
||||
* Users are not expected to implement this interface directly, but rather extends
|
||||
* from {@link BeanRegistrationCodeFragmentsDecorator} and only override the
|
||||
* necessary method(s).
|
||||
*
|
||||
* <p>Users are not expected to implement this interface directly, but rather
|
||||
* extends from {@link BeanRegistrationCodeFragmentsDecorator} and only override
|
||||
* the necessary method(s).
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
|
@ -48,12 +49,12 @@ import org.springframework.javapoet.CodeBlock;
|
|||
public interface BeanRegistrationCodeFragments {
|
||||
|
||||
/**
|
||||
* The variable name to used when creating the bean definition.
|
||||
* The variable name used when creating the bean definition.
|
||||
*/
|
||||
String BEAN_DEFINITION_VARIABLE = "beanDefinition";
|
||||
|
||||
/**
|
||||
* The variable name to used when creating the bean definition.
|
||||
* The variable name used when creating the bean definition.
|
||||
*/
|
||||
String INSTANCE_SUPPLIER_VARIABLE = "instanceSupplier";
|
||||
|
||||
|
@ -69,8 +70,7 @@ public interface BeanRegistrationCodeFragments {
|
|||
|
||||
/**
|
||||
* Generate the code that defines the new bean definition instance.
|
||||
* <p>
|
||||
* This should declare a variable named {@value BEAN_DEFINITION_VARIABLE}
|
||||
* <p>This should declare a variable named {@value BEAN_DEFINITION_VARIABLE}
|
||||
* so that further fragments can refer to the variable to further tune
|
||||
* the bean definition.
|
||||
* @param generationContext the generation context
|
||||
|
@ -94,14 +94,13 @@ public interface BeanRegistrationCodeFragments {
|
|||
|
||||
/**
|
||||
* Generate the code that sets the instance supplier on the bean definition.
|
||||
* <p>
|
||||
* The {@code postProcessors} represent methods to be exposed once the
|
||||
* <p>The {@code postProcessors} represent methods to be exposed once the
|
||||
* instance has been created to further configure it. Each method should
|
||||
* accept two parameters, the {@link RegisteredBean} and the bean
|
||||
* instance, and should return the modified bean instance.
|
||||
* @param generationContext the generation context
|
||||
* @param beanRegistrationCode the bean registration code
|
||||
* @param instanceSupplierCode the instance supplier code supplier code
|
||||
* @param instanceSupplierCode the instance supplier code
|
||||
* @param postProcessors any instance post processors that should be applied
|
||||
* @return the generated code
|
||||
* @see #generateInstanceSupplierCode
|
||||
|
|
|
@ -58,6 +58,7 @@ class BeanRegistrationCodeGenerator implements BeanRegistrationCode {
|
|||
this.codeFragments = codeFragments;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClassName getClassName() {
|
||||
return this.className;
|
||||
|
|
|
@ -245,7 +245,7 @@ class DefaultBeanRegistrationCodeFragments implements BeanRegistrationCodeFragme
|
|||
}
|
||||
|
||||
private boolean hasInstanceSupplier() {
|
||||
return this.registeredBean.getMergedBeanDefinition().getInstanceSupplier() != null;
|
||||
return (this.registeredBean.getMergedBeanDefinition().getInstanceSupplier() != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ public class InstanceSupplierCodeGenerator {
|
|||
this.allowDirectSupplierShortcut = allowDirectSupplierShortcut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate the instance supplier code.
|
||||
* @param registeredBean the bean to handle
|
||||
|
@ -165,7 +166,8 @@ public class InstanceSupplierCodeGenerator {
|
|||
hints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
||||
}
|
||||
|
||||
if (!isVisible(constructor, constructor.getDeclaringClass())) {
|
||||
if (!isVisible(constructor, constructor.getDeclaringClass()) ||
|
||||
registeredBean.getMergedBeanDefinition().hasMethodOverrides()) {
|
||||
return generateCodeForInaccessibleConstructor(descriptor,
|
||||
hints -> hints.registerConstructor(constructor, ExecutableMode.INVOKE));
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.beans.factory.support;
|
|||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -54,6 +55,20 @@ public class ReplaceOverride extends MethodOverride {
|
|||
this.methodReplacerBeanName = methodReplacerBeanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ReplaceOverride.
|
||||
* @param methodName the name of the method to override
|
||||
* @param methodReplacerBeanName the bean name of the {@link MethodReplacer}
|
||||
* @param typeIdentifiers a list of type identifiers for parameter types
|
||||
* @since 6.2.9
|
||||
*/
|
||||
public ReplaceOverride(String methodName, String methodReplacerBeanName, List<String> typeIdentifiers) {
|
||||
super(methodName);
|
||||
Assert.notNull(methodReplacerBeanName, "Method replacer bean name must not be null");
|
||||
this.methodReplacerBeanName = methodReplacerBeanName;
|
||||
this.typeIdentifiers.addAll(typeIdentifiers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of the bean implementing MethodReplacer.
|
||||
|
@ -71,6 +86,15 @@ public class ReplaceOverride extends MethodOverride {
|
|||
this.typeIdentifiers.add(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of registered type identifiers (fragments of a class string).
|
||||
* @since 6.2.9
|
||||
* @see #addTypeIdentifier
|
||||
*/
|
||||
public List<String> getTypeIdentifiers() {
|
||||
return Collections.unmodifiableList(this.typeIdentifiers);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method) {
|
||||
|
|
|
@ -32,9 +32,8 @@ import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
|
|||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
|
||||
/**
|
||||
* A collection of {@link BeanFactoryInitializationAotContribution AOT
|
||||
* contributions} obtained from {@link BeanFactoryInitializationAotProcessor AOT
|
||||
* processors}.
|
||||
* A collection of {@link BeanFactoryInitializationAotContribution AOT contributions}
|
||||
* obtained from {@link BeanFactoryInitializationAotProcessor AOT processors}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 6.0
|
||||
|
@ -48,14 +47,12 @@ class BeanFactoryInitializationAotContributions {
|
|||
this(beanFactory, AotServices.factoriesAndBeans(beanFactory));
|
||||
}
|
||||
|
||||
BeanFactoryInitializationAotContributions(DefaultListableBeanFactory beanFactory,
|
||||
AotServices.Loader loader) {
|
||||
BeanFactoryInitializationAotContributions(DefaultListableBeanFactory beanFactory, AotServices.Loader loader) {
|
||||
this.contributions = getContributions(beanFactory, getProcessors(loader));
|
||||
}
|
||||
|
||||
|
||||
private static List<BeanFactoryInitializationAotProcessor> getProcessors(
|
||||
AotServices.Loader loader) {
|
||||
private static List<BeanFactoryInitializationAotProcessor> getProcessors(AotServices.Loader loader) {
|
||||
List<BeanFactoryInitializationAotProcessor> processors = new ArrayList<>(
|
||||
loader.load(BeanFactoryInitializationAotProcessor.class).asList());
|
||||
processors.add(new RuntimeHintsBeanFactoryInitializationAotProcessor());
|
||||
|
@ -63,8 +60,8 @@ class BeanFactoryInitializationAotContributions {
|
|||
}
|
||||
|
||||
private List<BeanFactoryInitializationAotContribution> getContributions(
|
||||
DefaultListableBeanFactory beanFactory,
|
||||
List<BeanFactoryInitializationAotProcessor> processors) {
|
||||
DefaultListableBeanFactory beanFactory, List<BeanFactoryInitializationAotProcessor> processors) {
|
||||
|
||||
List<BeanFactoryInitializationAotContribution> contributions = new ArrayList<>();
|
||||
for (BeanFactoryInitializationAotProcessor processor : processors) {
|
||||
BeanFactoryInitializationAotContribution contribution = processAheadOfTime(processor, beanFactory);
|
||||
|
@ -75,8 +72,8 @@ class BeanFactoryInitializationAotContributions {
|
|||
return Collections.unmodifiableList(contributions);
|
||||
}
|
||||
|
||||
private @Nullable BeanFactoryInitializationAotContribution processAheadOfTime(BeanFactoryInitializationAotProcessor processor,
|
||||
DefaultListableBeanFactory beanFactory) {
|
||||
private @Nullable BeanFactoryInitializationAotContribution processAheadOfTime(
|
||||
BeanFactoryInitializationAotProcessor processor, DefaultListableBeanFactory beanFactory) {
|
||||
|
||||
try {
|
||||
return processor.processAheadOfTime(beanFactory);
|
||||
|
@ -92,6 +89,7 @@ class BeanFactoryInitializationAotContributions {
|
|||
|
||||
void applyTo(GenerationContext generationContext,
|
||||
BeanFactoryInitializationCode beanFactoryInitializationCode) {
|
||||
|
||||
for (BeanFactoryInitializationAotContribution contribution : this.contributions) {
|
||||
contribution.applyTo(generationContext, beanFactoryInitializationCode);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.context.aot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
@ -50,7 +51,9 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
|
|||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.MethodReplacer;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.beans.factory.support.ReplaceOverride;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.Employee;
|
||||
import org.springframework.beans.testfixture.beans.Pet;
|
||||
|
@ -80,6 +83,7 @@ import org.springframework.context.testfixture.context.annotation.LazyConstructo
|
|||
import org.springframework.context.testfixture.context.annotation.LazyFactoryMethodArgumentComponent;
|
||||
import org.springframework.context.testfixture.context.annotation.LazyResourceFieldComponent;
|
||||
import org.springframework.context.testfixture.context.annotation.LazyResourceMethodComponent;
|
||||
import org.springframework.context.testfixture.context.annotation.LookupComponent;
|
||||
import org.springframework.context.testfixture.context.annotation.PropertySourceConfiguration;
|
||||
import org.springframework.context.testfixture.context.annotation.QualifierConfiguration;
|
||||
import org.springframework.context.testfixture.context.annotation.ResourceComponent;
|
||||
|
@ -111,6 +115,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasSimpleBean() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.registerBeanDefinition("test", new RootBeanDefinition(SimpleComponent.class));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("test");
|
||||
|
@ -118,6 +123,99 @@ class ApplicationContextAotGeneratorTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasNoAotContributions() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
assertThat(compiled.getSourceFile())
|
||||
.contains("beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver())")
|
||||
.contains("beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE)");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasBeanFactoryInitializationAotProcessorExcludesProcessor() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.registerBeanDefinition("test",
|
||||
new RootBeanDefinition(NoOpBeanFactoryInitializationAotProcessor.class));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasBeanRegistrationAotProcessorExcludesProcessor() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.registerBeanDefinition("test",
|
||||
new RootBeanDefinition(NoOpBeanRegistrationAotProcessor.class));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithPropertySource() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(PropertySourceConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
ConfigurableEnvironment environment = freshApplicationContext.getEnvironment();
|
||||
PropertySource<?> propertySource = environment.getPropertySources().get("testp1");
|
||||
assertThat(propertySource).isNotNull();
|
||||
assertThat(propertySource.getProperty("from.p1")).isEqualTo("p1Value");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithQualifier() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(QualifierConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
QualifierConfiguration configuration = freshApplicationContext.getBean(QualifierConfiguration.class);
|
||||
assertThat(configuration).hasFieldOrPropertyWithValue("bean", "one");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithInjectionPoint() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(InjectionPointConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean("classToString"))
|
||||
.isEqualTo(InjectionPointConfiguration.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
@Test // gh-30689
|
||||
void processAheadOfTimeWithExplicitResolvableType() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(One.class);
|
||||
beanDefinition.setResolvedFactoryMethod(ReflectionUtils.findMethod(TestHierarchy.class, "oneBean"));
|
||||
// Override target type
|
||||
beanDefinition.setTargetType(Two.class);
|
||||
beanFactory.registerBeanDefinition("hierarchyBean", beanDefinition);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean(Two.class))
|
||||
.isInstanceOf(Implementation.class);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class Autowiring {
|
||||
|
||||
|
@ -128,6 +226,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
|
||||
applicationContext.registerBeanDefinition("autowiredComponent", new RootBeanDefinition(AutowiredComponent.class));
|
||||
registerIntegerBean(applicationContext, "number", 42);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number");
|
||||
|
@ -137,11 +236,56 @@ class ApplicationContextAotGeneratorTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasReplacer() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
registerBeanPostProcessor(applicationContext,
|
||||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredComponent.class);
|
||||
rbd.getMethodOverrides().addOverride(
|
||||
new ReplaceOverride("getCounter", "replacer"));
|
||||
applicationContext.registerBeanDefinition("autowiredComponent", rbd);
|
||||
registerIntegerBean(applicationContext, "number", 42);
|
||||
applicationContext.registerBean("replacer", DummyReplacer.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number", "replacer");
|
||||
AutowiredComponent bean = freshApplicationContext.getBean(AutowiredComponent.class);
|
||||
assertThat(bean.getEnvironment()).isSameAs(freshApplicationContext.getEnvironment());
|
||||
assertThat(bean.getCounter()).isEqualTo(44);
|
||||
assertThat(bean.getCounter(0)).isEqualTo(42);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasLookup() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
registerBeanPostProcessor(applicationContext,
|
||||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(LookupComponent.class);
|
||||
rbd.getMethodOverrides().addOverride(
|
||||
new ReplaceOverride("getCounter", "replacer", List.of( "Integer")));
|
||||
applicationContext.registerBeanDefinition("autowiredComponent", rbd);
|
||||
registerIntegerBean(applicationContext, "number", 42);
|
||||
applicationContext.registerBean("replacer", DummyReplacer.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number", "replacer");
|
||||
LookupComponent bean = freshApplicationContext.getBean(LookupComponent.class);
|
||||
assertThat(bean.getEnvironment()).isSameAs(freshApplicationContext.getEnvironment());
|
||||
assertThat(bean.getCounter()).isEqualTo(42);
|
||||
assertThat(bean.getCounter(0)).isEqualTo(44);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasAutowiringOnUnresolvedGeneric() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(GenericTemplateConfiguration.class);
|
||||
applicationContext.registerBean("autowiredComponent", AutowiredGenericTemplate.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
AutowiredGenericTemplate bean = freshApplicationContext.getBean(AutowiredGenericTemplate.class);
|
||||
|
@ -161,7 +305,6 @@ class ApplicationContextAotGeneratorTests {
|
|||
assertThat(runtimeHints.proxies().jdkProxyHints()).anySatisfy(proxyHint ->
|
||||
assertThat(proxyHint.getProxiedInterfaces()).isEqualTo(TypeReference.listOf(
|
||||
environment.getClass().getInterfaces())));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -225,15 +368,16 @@ class ApplicationContextAotGeneratorTests {
|
|||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
|
||||
applicationContext.registerBeanDefinition("testComponent", beanDefinition);
|
||||
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
|
||||
|
||||
testCompiledResult(generationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("testComponent");
|
||||
assertions.accept(freshApplicationContext.getBean("testComponent", type), generationContext);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class ResourceAutowiring {
|
||||
|
||||
|
@ -246,6 +390,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
registerStringBean(applicationContext, "text2", "hello2");
|
||||
registerIntegerBean(applicationContext, "number", 42);
|
||||
applicationContext.registerBeanDefinition("resourceComponent", new RootBeanDefinition(ResourceComponent.class));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("resourceComponent", "text", "text2", "number");
|
||||
|
@ -299,6 +444,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME, CommonAnnotationBeanPostProcessor.class);
|
||||
applicationContext.registerBeanDefinition("testComponent", beanDefinition);
|
||||
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
|
||||
|
||||
testCompiledResult(generationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("testComponent");
|
||||
|
@ -307,6 +453,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class InitDestroy {
|
||||
|
||||
|
@ -317,6 +464,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME, CommonAnnotationBeanPostProcessor.class);
|
||||
applicationContext.registerBeanDefinition("initDestroyComponent",
|
||||
new RootBeanDefinition(InitDestroyComponent.class));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("initDestroyComponent");
|
||||
|
@ -336,6 +484,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
beanDefinition.setInitMethodName("customInit");
|
||||
beanDefinition.setDestroyMethodName("customDestroy");
|
||||
applicationContext.registerBeanDefinition("initDestroyComponent", beanDefinition);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("initDestroyComponent");
|
||||
|
@ -345,94 +494,8 @@ class ApplicationContextAotGeneratorTests {
|
|||
assertThat(bean.events).containsExactly("init", "customInit", "destroy", "customDestroy");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasNoAotContributions() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
assertThat(compiled.getSourceFile())
|
||||
.contains("beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver())")
|
||||
.contains("beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE)");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasBeanFactoryInitializationAotProcessorExcludesProcessor() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.registerBeanDefinition("test",
|
||||
new RootBeanDefinition(NoOpBeanFactoryInitializationAotProcessor.class));
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasBeanRegistrationAotProcessorExcludesProcessor() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.registerBeanDefinition("test",
|
||||
new RootBeanDefinition(NoOpBeanRegistrationAotProcessor.class));
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithPropertySource() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(PropertySourceConfiguration.class);
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
ConfigurableEnvironment environment = freshApplicationContext.getEnvironment();
|
||||
PropertySource<?> propertySource = environment.getPropertySources().get("testp1");
|
||||
assertThat(propertySource).isNotNull();
|
||||
assertThat(propertySource.getProperty("from.p1")).isEqualTo("p1Value");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithQualifier() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(QualifierConfiguration.class);
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
QualifierConfiguration configuration = freshApplicationContext.getBean(QualifierConfiguration.class);
|
||||
assertThat(configuration).hasFieldOrPropertyWithValue("bean", "one");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWithInjectionPoint() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(InjectionPointConfiguration.class);
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean("classToString"))
|
||||
.isEqualTo(InjectionPointConfiguration.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
@Test // gh-30689
|
||||
void processAheadOfTimeWithExplicitResolvableType() {
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(One.class);
|
||||
beanDefinition.setResolvedFactoryMethod(ReflectionUtils.findMethod(TestHierarchy.class, "oneBean"));
|
||||
// Override target type
|
||||
beanDefinition.setTargetType(Two.class);
|
||||
beanFactory.registerBeanDefinition("hierarchyBean", beanDefinition);
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean(Two.class))
|
||||
.isInstanceOf(Implementation.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Nested
|
||||
@CompileWithForkedClassLoader
|
||||
|
@ -498,6 +561,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasCglibProxyUseProxy() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(CglibConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean("prefix", String.class)).isEqualTo("Hello0");
|
||||
|
@ -509,6 +573,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasCglibProxyAndAutowiring() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(AutowiredCglibConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
|
||||
context.setEnvironment(new MockEnvironment().withProperty("hello", "Hi"));
|
||||
|
@ -522,6 +587,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasCglibProxyAndMixedAutowiring() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(AutowiredMixedCglibConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
|
||||
context.setEnvironment(new MockEnvironment().withProperty("hello", "Hi")
|
||||
|
@ -536,6 +602,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasCglibProxyWithAnnotationsOnTheUserClasConstructor() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean("config", ValueCglibConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
|
||||
context.setEnvironment(new MockEnvironment().withProperty("name", "AOT World"));
|
||||
|
@ -550,6 +617,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
void processAheadOfTimeWhenHasCglibProxyWithArgumentsUseProxy() {
|
||||
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = createFreshApplicationContext(initializer);
|
||||
freshApplicationContext.setEnvironment(new MockEnvironment().withProperty("test.prefix", "Hi"));
|
||||
|
@ -571,9 +639,9 @@ class ApplicationContextAotGeneratorTests {
|
|||
private String toCglibClassSimpleName(Class<?> configClass) {
|
||||
return configClass.getSimpleName() + CGLIB_CONFIGURATION_CLASS_SUFFIX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class ActiveProfile {
|
||||
|
||||
|
@ -584,6 +652,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
if (aotProfiles.length != 0) {
|
||||
applicationContext.getEnvironment().setActiveProfiles(aotProfiles);
|
||||
}
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = new GenericApplicationContext();
|
||||
if (runtimeProfiles.length != 0) {
|
||||
|
@ -602,17 +671,18 @@ class ApplicationContextAotGeneratorTests {
|
|||
Arguments.of(new String[] { "aot", "prod" }, new String[] { "aot", "prod" }, new String[] { "aot", "prod" }),
|
||||
Arguments.of(new String[] { "default" }, new String[] {}, new String[] {}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class XmlSupport {
|
||||
|
||||
@Test
|
||||
void processAheadOfTimeWhenHasTypedStringValue() {
|
||||
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
|
||||
applicationContext
|
||||
.load(new ClassPathResource("applicationContextAotGeneratorTests-values.xml", getClass()));
|
||||
applicationContext.load(
|
||||
new ClassPathResource("applicationContextAotGeneratorTests-values.xml", getClass()));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
Employee employee = freshApplicationContext.getBean(Employee.class);
|
||||
|
@ -629,8 +699,9 @@ class ApplicationContextAotGeneratorTests {
|
|||
@Test
|
||||
void processAheadOfTimeWhenHasTypedStringValueWithType() {
|
||||
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
|
||||
applicationContext
|
||||
.load(new ClassPathResource("applicationContextAotGeneratorTests-values-types.xml", getClass()));
|
||||
applicationContext.load(
|
||||
new ClassPathResource("applicationContextAotGeneratorTests-values-types.xml", getClass()));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
Employee employee = freshApplicationContext.getBean(Employee.class);
|
||||
|
@ -645,8 +716,9 @@ class ApplicationContextAotGeneratorTests {
|
|||
@Test
|
||||
void processAheadOfTimeWhenHasTypedStringValueWithExpression() {
|
||||
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
|
||||
applicationContext
|
||||
.load(new ClassPathResource("applicationContextAotGeneratorTests-values-expressions.xml", getClass()));
|
||||
applicationContext.load(
|
||||
new ClassPathResource("applicationContextAotGeneratorTests-values-expressions.xml", getClass()));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
Employee employee = freshApplicationContext.getBean(Employee.class);
|
||||
|
@ -661,8 +733,9 @@ class ApplicationContextAotGeneratorTests {
|
|||
@Test
|
||||
void processAheadOfTimeWhenXmlHasBeanReferences() {
|
||||
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
|
||||
applicationContext
|
||||
.load(new ClassPathResource("applicationContextAotGeneratorTests-references.xml", getClass()));
|
||||
applicationContext.load(
|
||||
new ClassPathResource("applicationContextAotGeneratorTests-references.xml", getClass()));
|
||||
|
||||
testCompiledResult(applicationContext, (initializer, compiled) -> {
|
||||
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
|
||||
assertThat(freshApplicationContext.getBean("petInnerBean", Pet.class)
|
||||
|
@ -671,11 +744,11 @@ class ApplicationContextAotGeneratorTests {
|
|||
.getName()).isEqualTo("Dofi");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class ExceptionHanding {
|
||||
class ExceptionHandling {
|
||||
|
||||
@Test
|
||||
void failureProcessingBeanFactoryAotContribution() {
|
||||
|
@ -690,6 +763,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static void registerBeanPostProcessor(GenericApplicationContext applicationContext,
|
||||
String beanName, Class<?> beanPostProcessorClass) {
|
||||
|
||||
|
@ -714,7 +788,7 @@ class ApplicationContextAotGeneratorTests {
|
|||
.getBeanDefinition());
|
||||
}
|
||||
|
||||
private Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {
|
||||
private static Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {
|
||||
return hints -> assertThat(hints).noneMatch(hint ->
|
||||
hint.getProxiedInterfaces().get(0).equals(TypeReference.of(target)));
|
||||
}
|
||||
|
@ -769,7 +843,6 @@ class ApplicationContextAotGeneratorTests {
|
|||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -780,9 +853,9 @@ class ApplicationContextAotGeneratorTests {
|
|||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class FailingBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotProcessor {
|
||||
|
||||
@Override
|
||||
|
@ -791,4 +864,13 @@ class ApplicationContextAotGeneratorTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DummyReplacer implements MethodReplacer {
|
||||
|
||||
@Override
|
||||
public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
|
||||
return 44;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,17 +25,13 @@ public class AutowiredComponent {
|
|||
|
||||
private Integer counter;
|
||||
|
||||
public Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public Integer getCounter() {
|
||||
return this.counter;
|
||||
public Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
|
@ -43,4 +39,12 @@ public class AutowiredComponent {
|
|||
this.counter = counter;
|
||||
}
|
||||
|
||||
public Integer getCounter() {
|
||||
return this.counter;
|
||||
}
|
||||
|
||||
public Integer getCounter(Integer ignored) {
|
||||
return this.counter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2002-present 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.context.testfixture.context.annotation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Lookup;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
public abstract class LookupComponent {
|
||||
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
@Lookup
|
||||
public abstract Integer getCounter();
|
||||
|
||||
public Integer getCounter(Integer ignored) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@ public class HibernateQueryException extends InvalidDataAccessResourceUsageExcep
|
|||
*/
|
||||
public @Nullable String getQueryString() {
|
||||
QueryException cause = (QueryException) getCause();
|
||||
return cause == null ? null : cause.getQueryString();
|
||||
return (cause != null ? cause.getQueryString() : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -367,13 +367,11 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
|||
* the current class descriptor contained in the metadata reader.
|
||||
*/
|
||||
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
|
||||
if (this.entityTypeFilters != null) {
|
||||
for (TypeFilter filter : this.entityTypeFilters) {
|
||||
if (filter.match(reader, readerFactory)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue