Restore special instance supplier generation for inner classes
Closes gh-33683
This commit is contained in:
parent
b748cb38c5
commit
7ea0ac55cd
|
@ -276,7 +276,9 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
||||||
|
|
||||||
ValueHolder[] argumentValues = resolveArgumentValues(registeredBean, executable);
|
ValueHolder[] argumentValues = resolveArgumentValues(registeredBean, executable);
|
||||||
Set<String> autowiredBeanNames = new LinkedHashSet<>(resolved.length * 2);
|
Set<String> autowiredBeanNames = new LinkedHashSet<>(resolved.length * 2);
|
||||||
for (int i = 0; i < parameterCount; i++) {
|
int startIndex = (executable instanceof Constructor<?> constructor &&
|
||||||
|
ClassUtils.isInnerClass(constructor.getDeclaringClass())) ? 1 : 0;
|
||||||
|
for (int i = startIndex; i < parameterCount; i++) {
|
||||||
MethodParameter parameter = getMethodParameter(executable, i);
|
MethodParameter parameter = getMethodParameter(executable, i);
|
||||||
DependencyDescriptor descriptor = new DependencyDescriptor(parameter, true);
|
DependencyDescriptor descriptor = new DependencyDescriptor(parameter, true);
|
||||||
String shortcut = (this.shortcutBeanNames != null ? this.shortcutBeanNames[i] : null);
|
String shortcut = (this.shortcutBeanNames != null ? this.shortcutBeanNames[i] : null);
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class InstanceSupplierCodeGenerator {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new generator instance.
|
||||||
* @param generationContext the generation context
|
* @param generationContext the generation context
|
||||||
* @param className the class name of the bean to instantiate
|
* @param className the class name of the bean to instantiate
|
||||||
* @param generatedMethods the generated methods
|
* @param generatedMethods the generated methods
|
||||||
|
@ -158,47 +158,43 @@ public class InstanceSupplierCodeGenerator {
|
||||||
private CodeBlock generateCodeForConstructor(RegisteredBean registeredBean, Constructor<?> constructor) {
|
private CodeBlock generateCodeForConstructor(RegisteredBean registeredBean, Constructor<?> constructor) {
|
||||||
String beanName = registeredBean.getBeanName();
|
String beanName = registeredBean.getBeanName();
|
||||||
Class<?> beanClass = registeredBean.getBeanClass();
|
Class<?> beanClass = registeredBean.getBeanClass();
|
||||||
Class<?> declaringClass = constructor.getDeclaringClass();
|
|
||||||
|
|
||||||
Visibility accessVisibility = getAccessVisibility(registeredBean, constructor);
|
|
||||||
if (KotlinDetector.isKotlinReflectPresent() && KotlinDelegate.hasConstructorWithOptionalParameter(beanClass)) {
|
if (KotlinDetector.isKotlinReflectPresent() && KotlinDelegate.hasConstructorWithOptionalParameter(beanClass)) {
|
||||||
return generateCodeForInaccessibleConstructor(beanName, beanClass, constructor,
|
return generateCodeForInaccessibleConstructor(beanName, constructor,
|
||||||
hints -> hints.registerType(beanClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
hints -> hints.registerType(beanClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
||||||
}
|
}
|
||||||
else if (accessVisibility != Visibility.PRIVATE) {
|
|
||||||
return generateCodeForAccessibleConstructor(beanName, beanClass, constructor, declaringClass);
|
if (!isVisible(constructor, constructor.getDeclaringClass())) {
|
||||||
|
return generateCodeForInaccessibleConstructor(beanName, constructor,
|
||||||
|
hints -> hints.registerConstructor(constructor, ExecutableMode.INVOKE));
|
||||||
}
|
}
|
||||||
return generateCodeForInaccessibleConstructor(beanName, beanClass, constructor,
|
return generateCodeForAccessibleConstructor(beanName, constructor);
|
||||||
hints -> hints.registerConstructor(constructor, ExecutableMode.INVOKE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateCodeForAccessibleConstructor(String beanName, Class<?> beanClass,
|
private CodeBlock generateCodeForAccessibleConstructor(String beanName, Constructor<?> constructor) {
|
||||||
Constructor<?> constructor, Class<?> declaringClass) {
|
|
||||||
|
|
||||||
this.generationContext.getRuntimeHints().reflection().registerConstructor(
|
this.generationContext.getRuntimeHints().reflection().registerConstructor(
|
||||||
constructor, ExecutableMode.INTROSPECT);
|
constructor, ExecutableMode.INTROSPECT);
|
||||||
|
|
||||||
if (constructor.getParameterCount() == 0) {
|
if (constructor.getParameterCount() == 0) {
|
||||||
if (!this.allowDirectSupplierShortcut) {
|
if (!this.allowDirectSupplierShortcut) {
|
||||||
return CodeBlock.of("$T.using($T::new)", InstanceSupplier.class, declaringClass);
|
return CodeBlock.of("$T.using($T::new)", InstanceSupplier.class, constructor.getDeclaringClass());
|
||||||
}
|
}
|
||||||
if (!isThrowingCheckedException(constructor)) {
|
if (!isThrowingCheckedException(constructor)) {
|
||||||
return CodeBlock.of("$T::new", declaringClass);
|
return CodeBlock.of("$T::new", constructor.getDeclaringClass());
|
||||||
}
|
}
|
||||||
return CodeBlock.of("$T.of($T::new)", ThrowingSupplier.class, declaringClass);
|
return CodeBlock.of("$T.of($T::new)", ThrowingSupplier.class, constructor.getDeclaringClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method ->
|
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method ->
|
||||||
buildGetInstanceMethodForConstructor(
|
buildGetInstanceMethodForConstructor(method, beanName, constructor, PRIVATE_STATIC));
|
||||||
method, beanName, beanClass, constructor, declaringClass, PRIVATE_STATIC));
|
|
||||||
return generateReturnStatement(generatedMethod);
|
return generateReturnStatement(generatedMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateCodeForInaccessibleConstructor(String beanName, Class<?> beanClass,
|
private CodeBlock generateCodeForInaccessibleConstructor(String beanName,
|
||||||
Constructor<?> constructor, Consumer<ReflectionHints> hints) {
|
Constructor<?> constructor, Consumer<ReflectionHints> hints) {
|
||||||
|
|
||||||
CodeWarnings codeWarnings = new CodeWarnings();
|
CodeWarnings codeWarnings = new CodeWarnings();
|
||||||
codeWarnings.detectDeprecation(beanClass, constructor)
|
codeWarnings.detectDeprecation(constructor.getDeclaringClass(), constructor)
|
||||||
.detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType));
|
.detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType));
|
||||||
hints.accept(this.generationContext.getRuntimeHints().reflection());
|
hints.accept(this.generationContext.getRuntimeHints().reflection());
|
||||||
|
|
||||||
|
@ -206,32 +202,34 @@ public class InstanceSupplierCodeGenerator {
|
||||||
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
||||||
method.addModifiers(PRIVATE_STATIC);
|
method.addModifiers(PRIVATE_STATIC);
|
||||||
codeWarnings.suppress(method);
|
codeWarnings.suppress(method);
|
||||||
method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass));
|
method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, constructor.getDeclaringClass()));
|
||||||
method.addStatement(generateResolverForConstructor(beanClass, constructor));
|
method.addStatement(generateResolverForConstructor(constructor));
|
||||||
});
|
});
|
||||||
|
|
||||||
return generateReturnStatement(generatedMethod);
|
return generateReturnStatement(generatedMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildGetInstanceMethodForConstructor(MethodSpec.Builder method,
|
private void buildGetInstanceMethodForConstructor(MethodSpec.Builder method, String beanName,
|
||||||
String beanName, Class<?> beanClass, Constructor<?> constructor, Class<?> declaringClass,
|
Constructor<?> constructor, javax.lang.model.element.Modifier... modifiers) {
|
||||||
javax.lang.model.element.Modifier... modifiers) {
|
|
||||||
|
Class<?> declaringClass = constructor.getDeclaringClass();
|
||||||
|
|
||||||
CodeWarnings codeWarnings = new CodeWarnings();
|
CodeWarnings codeWarnings = new CodeWarnings();
|
||||||
codeWarnings.detectDeprecation(beanClass, constructor, declaringClass)
|
codeWarnings.detectDeprecation(declaringClass, constructor)
|
||||||
.detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType));
|
.detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType));
|
||||||
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
||||||
method.addModifiers(modifiers);
|
method.addModifiers(modifiers);
|
||||||
codeWarnings.suppress(method);
|
codeWarnings.suppress(method);
|
||||||
method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass));
|
method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, declaringClass));
|
||||||
|
|
||||||
CodeBlock.Builder code = CodeBlock.builder();
|
CodeBlock.Builder code = CodeBlock.builder();
|
||||||
code.add(generateResolverForConstructor(beanClass, constructor));
|
code.add(generateResolverForConstructor(constructor));
|
||||||
boolean hasArguments = constructor.getParameterCount() > 0;
|
boolean hasArguments = constructor.getParameterCount() > 0;
|
||||||
|
boolean onInnerClass = ClassUtils.isInnerClass(declaringClass);
|
||||||
|
|
||||||
CodeBlock arguments = hasArguments ?
|
CodeBlock arguments = hasArguments ?
|
||||||
new AutowiredArgumentsCodeGenerator(declaringClass, constructor)
|
new AutowiredArgumentsCodeGenerator(declaringClass, constructor)
|
||||||
.generateCode(constructor.getParameterTypes())
|
.generateCode(constructor.getParameterTypes(), (onInnerClass ? 1 : 0))
|
||||||
: NO_ARGS;
|
: NO_ARGS;
|
||||||
|
|
||||||
CodeBlock newInstance = generateNewInstanceCodeForConstructor(declaringClass, arguments);
|
CodeBlock newInstance = generateNewInstanceCodeForConstructor(declaringClass, arguments);
|
||||||
|
@ -239,24 +237,29 @@ public class InstanceSupplierCodeGenerator {
|
||||||
method.addStatement(code.build());
|
method.addStatement(code.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateResolverForConstructor(Class<?> beanClass, Constructor<?> constructor) {
|
private CodeBlock generateResolverForConstructor(Constructor<?> constructor) {
|
||||||
CodeBlock parameterTypes = generateParameterTypesCode(constructor.getParameterTypes());
|
CodeBlock parameterTypes = generateParameterTypesCode(constructor.getParameterTypes());
|
||||||
return CodeBlock.of("return $T.<$T>forConstructor($L)", BeanInstanceSupplier.class, beanClass, parameterTypes);
|
return CodeBlock.of("return $T.<$T>forConstructor($L)", BeanInstanceSupplier.class,
|
||||||
|
constructor.getDeclaringClass(), parameterTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateNewInstanceCodeForConstructor(Class<?> declaringClass, CodeBlock args) {
|
private CodeBlock generateNewInstanceCodeForConstructor(Class<?> declaringClass, CodeBlock args) {
|
||||||
|
if (ClassUtils.isInnerClass(declaringClass)) {
|
||||||
|
return CodeBlock.of("$L.getBeanFactory().getBean($T.class).new $L($L)",
|
||||||
|
REGISTERED_BEAN_PARAMETER_NAME, declaringClass.getEnclosingClass(),
|
||||||
|
declaringClass.getSimpleName(), args);
|
||||||
|
}
|
||||||
return CodeBlock.of("new $T($L)", declaringClass, args);
|
return CodeBlock.of("new $T($L)", declaringClass, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateCodeForFactoryMethod(
|
private CodeBlock generateCodeForFactoryMethod(
|
||||||
RegisteredBean registeredBean, Method factoryMethod, Class<?> targetClass) {
|
RegisteredBean registeredBean, Method factoryMethod, Class<?> targetClass) {
|
||||||
|
|
||||||
Visibility accessVisibility = getAccessVisibility(registeredBean, factoryMethod);
|
if (!isVisible(factoryMethod, targetClass)) {
|
||||||
if (accessVisibility != Visibility.PRIVATE) {
|
return generateCodeForInaccessibleFactoryMethod(registeredBean.getBeanName(), factoryMethod, targetClass);
|
||||||
return generateCodeForAccessibleFactoryMethod(registeredBean.getBeanName(), factoryMethod, targetClass,
|
|
||||||
registeredBean.getMergedBeanDefinition().getFactoryBeanName());
|
|
||||||
}
|
}
|
||||||
return generateCodeForInaccessibleFactoryMethod(registeredBean.getBeanName(), factoryMethod, targetClass);
|
return generateCodeForAccessibleFactoryMethod(registeredBean.getBeanName(), factoryMethod, targetClass,
|
||||||
|
registeredBean.getMergedBeanDefinition().getFactoryBeanName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName,
|
private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName,
|
||||||
|
@ -366,11 +369,13 @@ public class InstanceSupplierCodeGenerator {
|
||||||
return code.build();
|
return code.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Visibility getAccessVisibility(RegisteredBean registeredBean, Member member) {
|
private boolean isVisible(Member member, Class<?> targetClass) {
|
||||||
AccessControl beanTypeAccessControl = AccessControl.forResolvableType(registeredBean.getBeanType());
|
AccessControl classAccessControl = AccessControl.forClass(targetClass);
|
||||||
AccessControl memberAccessControl = AccessControl.forMember(member);
|
AccessControl memberAccessControl = AccessControl.forMember(member);
|
||||||
return AccessControl.lowest(beanTypeAccessControl, memberAccessControl).getVisibility();
|
Visibility visibility = AccessControl.lowest(classAccessControl, memberAccessControl).getVisibility();
|
||||||
}
|
return (visibility == Visibility.PUBLIC || (visibility != Visibility.PRIVATE &&
|
||||||
|
member.getDeclaringClass().getPackageName().equals(this.className.packageName())));
|
||||||
|
}
|
||||||
|
|
||||||
private CodeBlock generateParameterTypesCode(Class<?>[] parameterTypes) {
|
private CodeBlock generateParameterTypesCode(Class<?>[] parameterTypes) {
|
||||||
CodeBlock.Builder code = CodeBlock.builder();
|
CodeBlock.Builder code = CodeBlock.builder();
|
||||||
|
@ -392,6 +397,7 @@ public class InstanceSupplierCodeGenerator {
|
||||||
.anyMatch(Exception.class::isAssignableFrom);
|
.anyMatch(Exception.class::isAssignableFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class to avoid a hard dependency on Kotlin at runtime.
|
* Inner class to avoid a hard dependency on Kotlin at runtime.
|
||||||
*/
|
*/
|
||||||
|
@ -410,7 +416,6 @@ public class InstanceSupplierCodeGenerator {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,9 @@ import org.springframework.beans.testfixture.beans.factory.aot.SimpleBean;
|
||||||
import org.springframework.beans.testfixture.beans.factory.aot.SimpleBeanContract;
|
import org.springframework.beans.testfixture.beans.factory.aot.SimpleBeanContract;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration;
|
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.EnvironmentAwareComponent;
|
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.EnvironmentAwareComponent;
|
||||||
|
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.EnvironmentAwareComponentWithoutPublicConstructor;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.NoDependencyComponent;
|
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.NoDependencyComponent;
|
||||||
|
import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.NoDependencyComponentWithoutPublicConstructor;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.SimpleConfiguration;
|
import org.springframework.beans.testfixture.beans.factory.generator.SimpleConfiguration;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedBean;
|
import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedBean;
|
||||||
import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedConstructor;
|
import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedConstructor;
|
||||||
|
@ -119,10 +121,10 @@ class InstanceSupplierCodeGeneratorTests {
|
||||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(NoDependencyComponent.class);
|
RootBeanDefinition beanDefinition = new RootBeanDefinition(NoDependencyComponent.class);
|
||||||
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
||||||
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
||||||
NoDependencyComponent bean = getBean(beanDefinition, instanceSupplier);
|
Object bean = getBean(beanDefinition, instanceSupplier);
|
||||||
assertThat(bean).isInstanceOf(NoDependencyComponent.class);
|
assertThat(bean).isInstanceOf(NoDependencyComponent.class);
|
||||||
assertThat(compiled.getSourceFile()).contains(
|
assertThat(compiled.getSourceFile()).contains(
|
||||||
"InstanceSupplier.using(InnerComponentConfiguration.NoDependencyComponent::new");
|
"getBeanFactory().getBean(InnerComponentConfiguration.class).new NoDependencyComponent()");
|
||||||
});
|
});
|
||||||
assertThat(getReflectionHints().getTypeHint(NoDependencyComponent.class))
|
assertThat(getReflectionHints().getTypeHint(NoDependencyComponent.class))
|
||||||
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
|
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
|
||||||
|
@ -134,15 +136,44 @@ class InstanceSupplierCodeGeneratorTests {
|
||||||
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
||||||
this.beanFactory.registerSingleton("environment", new StandardEnvironment());
|
this.beanFactory.registerSingleton("environment", new StandardEnvironment());
|
||||||
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
||||||
EnvironmentAwareComponent bean = getBean(beanDefinition, instanceSupplier);
|
Object bean = getBean(beanDefinition, instanceSupplier);
|
||||||
assertThat(bean).isInstanceOf(EnvironmentAwareComponent.class);
|
assertThat(bean).isInstanceOf(EnvironmentAwareComponent.class);
|
||||||
assertThat(compiled.getSourceFile()).contains(
|
assertThat(compiled.getSourceFile()).contains(
|
||||||
"new InnerComponentConfiguration.EnvironmentAwareComponent(");
|
"getBeanFactory().getBean(InnerComponentConfiguration.class).new EnvironmentAwareComponent(");
|
||||||
});
|
});
|
||||||
assertThat(getReflectionHints().getTypeHint(EnvironmentAwareComponent.class))
|
assertThat(getReflectionHints().getTypeHint(EnvironmentAwareComponent.class))
|
||||||
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
|
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void generateWhenHasNonPublicConstructorWithInnerClassAndDefaultConstructor() {
|
||||||
|
RootBeanDefinition beanDefinition = new RootBeanDefinition(NoDependencyComponentWithoutPublicConstructor.class);
|
||||||
|
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
||||||
|
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
||||||
|
Object bean = getBean(beanDefinition, instanceSupplier);
|
||||||
|
assertThat(bean).isInstanceOf(NoDependencyComponentWithoutPublicConstructor.class);
|
||||||
|
assertThat(compiled.getSourceFile()).doesNotContain(
|
||||||
|
"getBeanFactory().getBean(InnerComponentConfiguration.class)");
|
||||||
|
});
|
||||||
|
assertThat(getReflectionHints().getTypeHint(NoDependencyComponentWithoutPublicConstructor.class))
|
||||||
|
.satisfies(hasConstructorWithMode(ExecutableMode.INVOKE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void generateWhenHasNonPublicConstructorWithInnerClassAndParameter() {
|
||||||
|
BeanDefinition beanDefinition = new RootBeanDefinition(EnvironmentAwareComponentWithoutPublicConstructor.class);
|
||||||
|
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
|
||||||
|
this.beanFactory.registerSingleton("environment", new StandardEnvironment());
|
||||||
|
compile(beanDefinition, (instanceSupplier, compiled) -> {
|
||||||
|
Object bean = getBean(beanDefinition, instanceSupplier);
|
||||||
|
assertThat(bean).isInstanceOf(EnvironmentAwareComponentWithoutPublicConstructor.class);
|
||||||
|
assertThat(compiled.getSourceFile()).doesNotContain(
|
||||||
|
"getBeanFactory().getBean(InnerComponentConfiguration.class)");
|
||||||
|
});
|
||||||
|
assertThat(getReflectionHints().getTypeHint(EnvironmentAwareComponentWithoutPublicConstructor.class))
|
||||||
|
.satisfies(hasConstructorWithMode(ExecutableMode.INVOKE));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void generateWhenHasConstructorWithGeneric() {
|
void generateWhenHasConstructorWithGeneric() {
|
||||||
BeanDefinition beanDefinition = new RootBeanDefinition(NumberHolderFactoryBean.class);
|
BeanDefinition beanDefinition = new RootBeanDefinition(NumberHolderFactoryBean.class);
|
||||||
|
|
|
@ -20,16 +20,28 @@ import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
public class InnerComponentConfiguration {
|
public class InnerComponentConfiguration {
|
||||||
|
|
||||||
public static class NoDependencyComponent {
|
public class NoDependencyComponent {
|
||||||
|
|
||||||
public NoDependencyComponent() {
|
public NoDependencyComponent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EnvironmentAwareComponent {
|
public class EnvironmentAwareComponent {
|
||||||
|
|
||||||
public EnvironmentAwareComponent(Environment environment) {
|
public EnvironmentAwareComponent(Environment environment) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NoDependencyComponentWithoutPublicConstructor {
|
||||||
|
|
||||||
|
NoDependencyComponentWithoutPublicConstructor() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EnvironmentAwareComponentWithoutPublicConstructor {
|
||||||
|
|
||||||
|
EnvironmentAwareComponentWithoutPublicConstructor(Environment environment) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue