Enable cglib proxy for configuration classes if necessary

This commit updates code generation to customize the instantiation of
a configuration class that requires a proxy. Rather than instantiating
the raw class, the proxy is used.

Closes gh-29107
This commit is contained in:
Stephane Nicoll
2022-09-13 12:49:03 +02:00
parent f2e9d112b1
commit 2f20d6322b
11 changed files with 259 additions and 45 deletions

View File

@@ -43,6 +43,7 @@ import org.springframework.beans.factory.support.BeanDefinitionValueResolver;
import org.springframework.beans.factory.support.InstanceSupplier;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.support.SimpleInstantiationStrategy;
import org.springframework.core.CollectionFactory;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
@@ -207,9 +208,24 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
Executable executable = this.lookup.get(registeredBean);
AutowiredArguments arguments = resolveArguments(registeredBean, executable);
if (this.generator != null) {
return this.generator.apply(registeredBean, arguments);
return invokeBeanSupplier(executable, () ->
this.generator.apply(registeredBean, arguments));
}
return invokeBeanSupplier(executable, () ->
instantiate(registeredBean.getBeanFactory(), executable, arguments.toArray()));
}
private T invokeBeanSupplier(Executable executable, ThrowingSupplier<T> beanSupplier) {
if (!(executable instanceof Method)) {
return beanSupplier.get();
}
try {
SimpleInstantiationStrategy.setCurrentlyInvokedFactoryMethod((Method) executable);
return beanSupplier.get();
}
finally {
SimpleInstantiationStrategy.setCurrentlyInvokedFactoryMethod(null);
}
return instantiate(registeredBean.getBeanFactory(), executable, arguments.toArray());
}
@Nullable

View File

@@ -109,8 +109,7 @@ class InstanceSupplierCodeGenerator {
String beanName = registeredBean.getBeanName();
Class<?> beanClass = registeredBean.getBeanClass();
Class<?> declaringClass = ClassUtils
.getUserClass(constructor.getDeclaringClass());
Class<?> declaringClass = constructor.getDeclaringClass();
boolean dependsOnBean = ClassUtils.isInnerClass(declaringClass);
Visibility accessVisibility = getAccessVisibility(registeredBean, constructor);
if (accessVisibility != Visibility.PRIVATE) {

View File

@@ -53,6 +53,14 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
return currentlyInvokedFactoryMethod.get();
}
/**
* Set the factory method currently being invoked or {@code null} to reset.
* @param method the factory method currently being invoked or {@code null}
*/
public static void setCurrentlyInvokedFactoryMethod(@Nullable Method method) {
currentlyInvokedFactoryMethod.set(method);
}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {