Polishing.

Reformat code and reorder methods according to visibility. Reduce type and method visibility where applicable.

See #2680
Original pull request: #2682.
This commit is contained in:
Mark Paluch
2022-10-04 15:45:04 +02:00
parent e7cc9a6104
commit 9c993e22f5
8 changed files with 124 additions and 100 deletions

View File

@@ -48,6 +48,15 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
private final Log logger = LogFactory.getLog(getClass());
private @Nullable String moduleIdentifier;
public void setModuleIdentifier(@Nullable String moduleIdentifier) {
this.moduleIdentifier = moduleIdentifier;
}
@Nullable
public String getModuleIdentifier() {
return this.moduleIdentifier;
}
@Override
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
@@ -59,18 +68,20 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
return contribute(AotContext.from(beanFactory), resolveManagedTypes(registeredBean), registeredBean);
}
ManagedTypes resolveManagedTypes(RegisteredBean registeredBean) {
private ManagedTypes resolveManagedTypes(RegisteredBean registeredBean) {
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
if (beanDefinition.hasConstructorArgumentValues()) {
ValueHolder indexedArgumentValue = beanDefinition.getConstructorArgumentValues().getIndexedArgumentValue(0, null);
Object value = indexedArgumentValue.getValue();
if (value instanceof Collection<?> values) {
if (values.stream().allMatch(it -> it instanceof Class)) {
return ManagedTypes.fromIterable((Collection<Class<?>>) values);
}
if (value instanceof Collection<?> values && values.stream().allMatch(it -> it instanceof Class)) {
return ManagedTypes.fromIterable((Collection<Class<?>>) values);
}
}
if (logger.isDebugEnabled()) {
logger.debug(
String.format("ManagedTypes BeanDefinition '%s' does serve arguments. Trying to resolve bean instance.",
@@ -93,29 +104,18 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
return ManagedTypes.empty();
}
protected boolean isMatch(@Nullable Class<?> beanType, @Nullable String beanName) {
return matchesByType(beanType) && matchesPrefix(beanName);
}
protected boolean matchesByType(@Nullable Class<?> beanType) {
return beanType != null && ClassUtils.isAssignable(ManagedTypes.class, beanType);
}
protected boolean matchesPrefix(@Nullable String beanName) {
return StringUtils.startsWithIgnoreCase(beanName, getModuleIdentifier());
}
/**
* Hook to provide a customized flavor of {@link BeanRegistrationAotContribution}. By overriding this method calls to
* {@link #contributeType(ResolvableType, GenerationContext)} might no longer be issued.
*
* @param aotContext never {@literal null}.
* @param managedTypes never {@literal null}.
* @return new instance of {@link ManagedTypesBeanRegistrationAotProcessor} or {@literal null} if nothing to do.
* @return new instance of {@link BeanRegistrationAotContribution} or {@literal null} if nothing to do.
*/
@Nullable
protected BeanRegistrationAotContribution contribute(AotContext aotContext, ManagedTypes managedTypes, RegisteredBean registeredBean) {
return new ManagedTypesRegistrationAotContribution(aotContext, managedTypes, registeredBean, this::contributeType);
protected BeanRegistrationAotContribution contribute(AotContext aotContext, ManagedTypes managedTypes,
RegisteredBean registeredBean) {
return new ManagedTypesRegistrationAotContribution(managedTypes, registeredBean, this::contributeType);
}
/**
@@ -138,12 +138,15 @@ public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistratio
annotation -> TypeContributor.contribute(annotation.getType(), annotationNamespaces, generationContext));
}
public void setModuleIdentifier(@Nullable String moduleIdentifier) {
this.moduleIdentifier = moduleIdentifier;
protected boolean isMatch(@Nullable Class<?> beanType, @Nullable String beanName) {
return matchesByType(beanType) && matchesPrefix(beanName);
}
@Nullable
public String getModuleIdentifier() {
return this.moduleIdentifier;
protected boolean matchesByType(@Nullable Class<?> beanType) {
return beanType != null && ClassUtils.isAssignable(ManagedTypes.class, beanType);
}
protected boolean matchesPrefix(@Nullable String beanName) {
return StringUtils.startsWithIgnoreCase(beanName, getModuleIdentifier());
}
}

View File

@@ -50,51 +50,42 @@ import org.springframework.util.ReflectionUtils;
* {@link BeanRegistrationAotContribution#customizeBeanRegistrationCodeFragments(GenerationContext, BeanRegistrationCodeFragments)}.
* The generated code resolves potential factory methods accepting either a {@link ManagedTypes} instance, or a
* {@link List} of either {@link Class} or {@link String} (classname) values.
*
* <pre>
* <code>
*
* <pre class="code">
* public static InstanceSupplier&lt;ManagedTypes&gt; instance() {
* return (registeredBean) -> {
* var types = List.of("com.example.A", "com.example.B");
* return ManagedTypes.ofStream(types.stream().map(it -> ClassUtils.forName(it, registeredBean.getBeanFactory().getBeanClassLoader())));
* }
* }
* </code>
* </pre>
*
* @author John Blum
* @author Christoph Strobl
* @author Mark Paluch
* @see org.springframework.beans.factory.aot.BeanRegistrationAotContribution
* @since 3.0.0
* @since 3.0
*/
public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContribution {
class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContribution {
private final AotContext aotContext;
private final ManagedTypes managedTypes;
private final Lazy<List<Class<?>>> sourceTypes;
private final BiConsumer<ResolvableType, GenerationContext> contributionAction;
private final RegisteredBean source;
public ManagedTypesRegistrationAotContribution(AotContext aotContext, @Nullable ManagedTypes managedTypes,
RegisteredBean registeredBean, BiConsumer<ResolvableType, GenerationContext> contributionAction) {
public ManagedTypesRegistrationAotContribution(ManagedTypes managedTypes, RegisteredBean registeredBean,
BiConsumer<ResolvableType, GenerationContext> contributionAction) {
this.aotContext = aotContext;
this.managedTypes = managedTypes;
this.sourceTypes = Lazy.of(managedTypes::toList);
this.contributionAction = contributionAction;
this.source = registeredBean;
}
protected AotContext getAotContext() {
return this.aotContext;
}
protected ManagedTypes getManagedTypes() {
return managedTypes == null ? ManagedTypes.empty() : managedTypes;
}
@Override
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
List<Class<?>> types = getManagedTypes().toList();
List<Class<?>> types = sourceTypes.get();
if (!types.isEmpty()) {
TypeCollector.inspect(types).forEach(type -> contributionAction.accept(type, generationContext));
@@ -109,7 +100,7 @@ public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAo
return codeFragments;
}
ManagedTypesInstanceCodeFragment fragment = new ManagedTypesInstanceCodeFragment(getManagedTypes(), source,
ManagedTypesInstanceCodeFragment fragment = new ManagedTypesInstanceCodeFragment(sourceTypes.get(), source,
codeFragments);
return fragment.canGenerateCode() ? fragment : codeFragments;
}
@@ -119,32 +110,27 @@ public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAo
return source;
}
/**
* Class used to generate the fragment of code needed to define a {@link ManagedTypes} bean from previously discovered
* managed types.
*/
static class ManagedTypesInstanceCodeFragment extends BeanRegistrationCodeFragments {
private ManagedTypes sourceTypes;
private RegisteredBean source;
private Lazy<Method> instanceMethod = Lazy.of(this::findInstanceFactory);
public static final ResolvableType LIST_TYPE = ResolvableType.forType(List.class);
public static final ResolvableType MANAGED_TYPES_TYPE = ResolvableType.forType(ManagedTypes.class);
private final List<Class<?>> sourceTypes;
private final RegisteredBean source;
private final Lazy<Method> instanceMethod = Lazy.of(this::findInstanceFactory);
protected ManagedTypesInstanceCodeFragment(ManagedTypes managedTypes, RegisteredBean source,
protected ManagedTypesInstanceCodeFragment(List<Class<?>> sourceTypes, RegisteredBean source,
BeanRegistrationCodeFragments codeFragments) {
super(codeFragments);
this.sourceTypes = managedTypes;
this.sourceTypes = sourceTypes;
this.source = source;
}
/**
* @return {@literal true} if the instance method code can be generated. {@literal false} otherwise.
*/
boolean canGenerateCode() {
if (ObjectUtils.nullSafeEquals(source.getBeanClass(), ManagedTypes.class)) {
return true;
}
return instanceMethod.getNullable() != null;
}
@Override
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
BeanRegistrationCode beanRegistrationCode, Executable constructorOrFactoryMethod,
@@ -156,33 +142,20 @@ public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAo
return CodeBlock.of("$T.$L()", beanRegistrationCode.getClassName(), generatedMethod.getName());
}
private CodeBlock toCodeBlock(List<Class<?>> values, boolean allPublic) {
/**
* @return {@literal true} if the instance method code can be generated. {@literal false} otherwise.
*/
boolean canGenerateCode() {
if (allPublic) {
return CodeBlock.join(values.stream().map(value -> CodeBlock.of("$T.class", value)).toList(), ", ");
if (ObjectUtils.nullSafeEquals(source.getBeanClass(), ManagedTypes.class)) {
return true;
}
return CodeBlock.join(values.stream().map(value -> CodeBlock.of("$S", value.getName())).toList(), ", ");
}
private Method findInstanceFactory() {
for (Method beanMethod : ReflectionUtils.getDeclaredMethods(source.getBeanClass())) {
if (beanMethod.getParameterCount() == 1 && java.lang.reflect.Modifier.isPublic(beanMethod.getModifiers())
&& java.lang.reflect.Modifier.isStatic(beanMethod.getModifiers())) {
ResolvableType parameterType = ResolvableType.forMethodParameter(beanMethod, 0, source.getBeanClass());
if (parameterType.isAssignableFrom(ResolvableType.forType(List.class))
|| parameterType.isAssignableFrom(ResolvableType.forType(ManagedTypes.class))) {
return beanMethod;
}
}
}
return null;
return instanceMethod.getNullable() != null;
}
void generateInstanceFactory(Builder method) {
List<Class<?>> sourceTypes = this.sourceTypes.toList();
boolean allSourceTypesVisible = sourceTypes.stream()
.allMatch(it -> AccessVisibility.PUBLIC.equals(AccessVisibility.forClass(it)));
@@ -207,6 +180,7 @@ public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAo
.addStatement("throw new $T($S, e)", IllegalArgumentException.class, "Cannot to load type").endControlFlow()
.endControlFlow("))").build());
}
if (ObjectUtils.nullSafeEquals(source.getBeanClass(), ManagedTypes.class)) {
builder.add("return managedTypes");
} else {
@@ -221,8 +195,42 @@ public class ManagedTypesRegistrationAotContribution implements RegisteredBeanAo
instanceFactoryMethod.getName(), "managedTypes");
}
}
builder.endControlFlow(")");
method.addCode(builder.build());
}
private CodeBlock toCodeBlock(List<Class<?>> values, boolean allPublic) {
if (allPublic) {
return CodeBlock.join(values.stream().map(value -> CodeBlock.of("$T.class", value)).toList(), ", ");
}
return CodeBlock.join(values.stream().map(value -> CodeBlock.of("$S", value.getName())).toList(), ", ");
}
@Nullable
private Method findInstanceFactory() {
for (Method beanMethod : ReflectionUtils.getDeclaredMethods(source.getBeanClass())) {
if (!isInstanceFactory(beanMethod)) {
continue;
}
ResolvableType parameterType = ResolvableType.forMethodParameter(beanMethod, 0, source.getBeanClass());
if (parameterType.isAssignableFrom(LIST_TYPE) || parameterType.isAssignableFrom(MANAGED_TYPES_TYPE)) {
return beanMethod;
}
}
return null;
}
private static boolean isInstanceFactory(Method beanMethod) {
return beanMethod.getParameterCount() == 1 //
&& java.lang.reflect.Modifier.isPublic(beanMethod.getModifiers()) //
&& java.lang.reflect.Modifier.isStatic(beanMethod.getModifiers());
}
}
}

View File

@@ -19,9 +19,16 @@ import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.support.RegisteredBean;
/**
* Extension to {@link BeanRegistrationAotContribution} that bases its contribution on a {@link RegisteredBean}. This
* interface exposes its {@link #getSource() source}.
*
* @author Christoph Strobl
* @since 3.0
*/
public interface RegisteredBeanAotContribution extends BeanRegistrationAotContribution {
/**
* @return the source {@link RegisteredBean}.
*/
RegisteredBean getSource();
}

View File

@@ -36,7 +36,7 @@ import org.springframework.util.ClassUtils;
*
* @author Christoph Strobl
* @author John Blum
* @since 3.0.0
* @since 3.0
*/
class RepositoryBeanDefinitionReader {

View File

@@ -61,7 +61,7 @@ import org.springframework.util.StringUtils;
*
* @author Christoph Strobl
* @author John Blum
* @since 3.0.0
* @since 3.0
*/
@SuppressWarnings("unused")
public class RepositoryRegistrationAotProcessor implements BeanRegistrationAotProcessor, BeanFactoryAware {