Skip to content

Commit

Permalink
Avoid double proxying for @resource @lazy fallback autowiring
Browse files Browse the repository at this point in the history
Includes refactored @resource resolver for AOT with lazy resolution support.

Closes gh-31447
See gh-29614
  • Loading branch information
jhoeller committed Dec 12, 2023
1 parent 6bb9775 commit 6dcba4d
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 457 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
Expand Down Expand Up @@ -375,6 +375,16 @@ public Class<?> getDependencyType() {
}
}

/**
* Determine whether this dependency supports lazy resolution,
* e.g. through extra proxying. The default is {@code true}.
* @since 6.1.2
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getLazyResolutionProxyIfNecessary
*/
public boolean supportsLazyResolution() {
return true;
}


@Override
public boolean equals(@Nullable Object other) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1343,14 +1343,14 @@ else if (ObjectFactory.class == descriptor.getDependencyType() ||
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
else if (descriptor.supportsLazyResolution()) {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
if (result != null) {
return result;
}
return result;
}
return doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.aot.ResourceFieldValueResolver;
import org.springframework.context.aot.ResourceMethodArgumentResolver;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.javapoet.ClassName;
Expand Down Expand Up @@ -501,16 +498,9 @@ public Class<?> getTargetClass() {
return element.lookupType;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
return getResource(element, requestingBeanName);
}
@Override
public void releaseTarget(Object target) {
}
};

ProxyFactory pf = new ProxyFactory();
Expand Down Expand Up @@ -655,12 +645,23 @@ public final Class<?> getLookupType() {
*/
public final DependencyDescriptor getDependencyDescriptor() {
if (this.isField) {
return new LookupDependencyDescriptor((Field) this.member, this.lookupType);
return new ResourceElementResolver.LookupDependencyDescriptor(
(Field) this.member, this.lookupType, isLazyLookup());
}
else {
return new LookupDependencyDescriptor((Method) this.member, this.lookupType);
return new ResourceElementResolver.LookupDependencyDescriptor(
(Method) this.member, this.lookupType, isLazyLookup());
}
}

/**
* Determine whether this dependency is marked for lazy lookup.
* The default is {@code false}.
* @since 6.1.2
*/
boolean isLazyLookup() {
return false;
}
}


Expand Down Expand Up @@ -707,6 +708,11 @@ protected Object getResourceToInject(Object target, @Nullable String requestingB
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}

@Override
boolean isLazyLookup() {
return this.lazyLookup;
}
}


Expand Down Expand Up @@ -753,6 +759,11 @@ protected Object getResourceToInject(Object target, @Nullable String requestingB
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}

@Override
boolean isLazyLookup() {
return this.lazyLookup;
}
}


Expand Down Expand Up @@ -812,30 +823,6 @@ else if (this.isDefaultName && !StringUtils.hasLength(this.mappedName)) {
}


/**
* Extension of the DependencyDescriptor class,
* overriding the dependency type with the specified resource type.
*/
private static class LookupDependencyDescriptor extends DependencyDescriptor {

private final Class<?> lookupType;

public LookupDependencyDescriptor(Field field, Class<?> lookupType) {
super(field, true);
this.lookupType = lookupType;
}

public LookupDependencyDescriptor(Method method, Class<?> lookupType) {
super(new MethodParameter(method, 0), true);
this.lookupType = lookupType;
}

@Override
public Class<?> getDependencyType() {
return this.lookupType;
}
}

/**
* {@link BeanRegistrationAotContribution} to inject resources on fields and methods.
*/
Expand Down Expand Up @@ -924,11 +911,11 @@ private CodeBlock generateMethodStatementForField(ClassName targetClassName,

private CodeBlock generateFieldResolverCode(Field field, LookupElement lookupElement) {
if (lookupElement.isDefaultName) {
return CodeBlock.of("$T.$L($S)", ResourceFieldValueResolver.class,
return CodeBlock.of("$T.$L($S)", ResourceElementResolver.class,
"forField", field.getName());
}
else {
return CodeBlock.of("$T.$L($S, $S)", ResourceFieldValueResolver.class,
return CodeBlock.of("$T.$L($S, $S)", ResourceElementResolver.class,
"forField", field.getName(), lookupElement.getName());
}
}
Expand All @@ -940,7 +927,7 @@ private CodeBlock generateMethodStatementForMethod(ClassName targetClassName,
AccessControl accessControl = AccessControl.forMember(method);
if (!accessControl.isAccessibleFrom(targetClassName)) {
hints.reflection().registerMethod(method, ExecutableMode.INVOKE);
return CodeBlock.of("$L.resolveAndInvoke($L, $L)", resolver,
return CodeBlock.of("$L.resolveAndSet($L, $L)", resolver,
REGISTERED_BEAN_PARAMETER, INSTANCE_PARAMETER);
}
hints.reflection().registerMethod(method, ExecutableMode.INTROSPECT);
Expand All @@ -951,11 +938,11 @@ private CodeBlock generateMethodStatementForMethod(ClassName targetClassName,

private CodeBlock generateMethodResolverCode(Method method, LookupElement lookupElement) {
if (lookupElement.isDefaultName) {
return CodeBlock.of("$T.$L($S, $T.class)", ResourceMethodArgumentResolver.class,
return CodeBlock.of("$T.$L($S, $T.class)", ResourceElementResolver.class,
"forMethod", method.getName(), lookupElement.getLookupType());
}
else {
return CodeBlock.of("$T.$L($S, $T.class, $S)", ResourceMethodArgumentResolver.class,
return CodeBlock.of("$T.$L($S, $T.class, $S)", ResourceElementResolver.class,
"forMethod", method.getName(), lookupElement.getLookupType(), lookupElement.getName());
}
}
Expand Down

0 comments on commit 6dcba4d

Please sign in to comment.