diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotFactoriesLoader.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotFactoriesLoader.java
index a57134b3bc1..a3f1f2051f5 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotFactoriesLoader.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotFactoriesLoader.java
@@ -30,8 +30,8 @@ import org.springframework.util.Assert;
/**
* AOT specific factory loading mechanism for internal use within the framework.
- *
- * Loads and instantiates factories of a given type from
+ *
+ *
Loads and instantiates factories of a given type from
* {@value #FACTORIES_RESOURCE_LOCATION} and merges them with matching beans
* from a {@link ListableBeanFactory}.
*
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/AotFactoriesLoaderTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/AotFactoriesLoaderTests.java
index d252a3663ed..19b1b3c80a0 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/AotFactoriesLoaderTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/AotFactoriesLoaderTests.java
@@ -56,22 +56,14 @@ class AotFactoriesLoaderTests {
beanFactory.registerSingleton("b1", new TestFactoryImpl(0, "b1"));
beanFactory.registerSingleton("b2", new TestFactoryImpl(2, "b2"));
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();
- springFactoriesLoader.addInstance(TestFactory.class,
- new TestFactoryImpl(1, "l1"));
- springFactoriesLoader.addInstance(TestFactory.class,
- new TestFactoryImpl(3, "l2"));
- AotFactoriesLoader loader = new AotFactoriesLoader(beanFactory,
- springFactoriesLoader);
+ springFactoriesLoader.addInstance(TestFactory.class, new TestFactoryImpl(1, "l1"));
+ springFactoriesLoader.addInstance(TestFactory.class, new TestFactoryImpl(3, "l2"));
+ AotFactoriesLoader loader = new AotFactoriesLoader(beanFactory, springFactoriesLoader);
List loaded = loader.load(TestFactory.class);
- assertThat(loaded).hasSize(4);
- assertThat(loaded.get(0)).hasToString("b1");
- assertThat(loaded.get(1)).hasToString("l1");
- assertThat(loaded.get(2)).hasToString("b2");
- assertThat(loaded.get(3)).hasToString("l2");
+ assertThat(loaded).map(Object::toString).containsExactly("b1", "l1", "b2", "l2");
}
- static interface TestFactory {
-
+ interface TestFactory {
}
static class TestFactoryImpl implements TestFactory, Ordered {
diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
index dc2a952b065..aca3464a7fd 100644
--- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
+++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
@@ -18,7 +18,6 @@ package org.springframework.core.io.support;
import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
@@ -69,15 +68,16 @@ import org.springframework.util.StringUtils;
*
* where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1}
* and {@code MyServiceImpl2} are two implementations.
- *
- * Implementation classes must have a single resolvable constructor that will
+ *
+ *
Implementation classes must have a single resolvable constructor that will
* be used to create the instance, either:
*
* - a primary or single constructor
* - a single public constructor
* - the default constructor
*
- * If the resolvable constructor has arguments, a suitable {@link ArgumentResolver
+ *
+ * If the resolvable constructor has arguments, a suitable {@link ArgumentResolver
* ArgumentResolver} should be provided. To customize how instantiation failures
* are handled, consider providing a {@link FailureHandler FailureHandler}.
*
@@ -223,7 +223,7 @@ public class SpringFactoriesLoader {
try {
Class> factoryImplementationClass = ClassUtils.forName(implementationName, this.classLoader);
Assert.isTrue(type.isAssignableFrom(factoryImplementationClass),
- () -> "Class [" + implementationName + "] is not assignable to factory type [" + type.getName() + "]");
+ () -> "Class [%s] is not assignable to factory type [%s]".formatted(implementationName, type.getName()));
FactoryInstantiator factoryInstantiator = FactoryInstantiator.forClass(factoryImplementationClass);
return factoryInstantiator.instantiate(argumentResolver);
}
@@ -319,20 +319,12 @@ public class SpringFactoriesLoader {
*/
public static SpringFactoriesLoader forResourceLocation(@Nullable ClassLoader classLoader, String resourceLocation) {
Assert.hasText(resourceLocation, "'resourceLocation' must not be empty");
- ClassLoader resourceClassLoader = (classLoader != null) ? classLoader
- : SpringFactoriesLoader.class.getClassLoader();
- Map loaders = SpringFactoriesLoader.cache.get(resourceClassLoader);
- if (loaders == null) {
- loaders = new ConcurrentReferenceHashMap<>();
- SpringFactoriesLoader.cache.put(resourceClassLoader, loaders);
- }
- SpringFactoriesLoader loader = loaders.get(resourceLocation);
- if (loader == null) {
- Map> factories = loadFactoriesResource(resourceClassLoader, resourceLocation);
- loader = new SpringFactoriesLoader(classLoader, factories);
- loaders.put(resourceLocation, loader);
- }
- return loader;
+ ClassLoader resourceClassLoader = (classLoader != null ? classLoader :
+ SpringFactoriesLoader.class.getClassLoader());
+ Map loaders = SpringFactoriesLoader.cache.computeIfAbsent(
+ resourceClassLoader, key -> new ConcurrentReferenceHashMap<>());
+ return loaders.computeIfAbsent(resourceLocation, key ->
+ new SpringFactoriesLoader(classLoader, loadFactoriesResource(resourceClassLoader, resourceLocation)));
}
static Map> loadFactoriesResource(ClassLoader classLoader, String resourceLocation) {
@@ -394,7 +386,8 @@ public class SpringFactoriesLoader {
@SuppressWarnings("unchecked")
static FactoryInstantiator forClass(Class> factoryImplementationClass) {
Constructor> constructor = findConstructor(factoryImplementationClass);
- Assert.state(constructor != null, "Class [" + factoryImplementationClass.getName() + "] has no suitable constructor");
+ Assert.state(constructor != null, () ->
+ "Class [%s] has no suitable constructor".formatted(factoryImplementationClass.getName()));
return new FactoryInstantiator<>((Constructor) constructor);
}
@@ -413,8 +406,8 @@ public class SpringFactoriesLoader {
@Nullable
private static Constructor> findPrimaryKotlinConstructor(Class> factoryImplementationClass) {
- return (isKotlinType(factoryImplementationClass)
- ? KotlinDelegate.findPrimaryConstructor(factoryImplementationClass) : null);
+ return (isKotlinType(factoryImplementationClass) ?
+ KotlinDelegate.findPrimaryConstructor(factoryImplementationClass) : null);
}
private static boolean isKotlinType(Class> factoryImplementationClass) {
@@ -440,12 +433,12 @@ public class SpringFactoriesLoader {
/**
- * Inner class to avoid a hard dependency on Kotlin at runtime.
+ * Nested class to avoid a hard dependency on Kotlin at runtime.
*/
private static class KotlinDelegate {
@Nullable
- public static Constructor findPrimaryConstructor(Class clazz) {
+ static Constructor findPrimaryConstructor(Class clazz) {
try {
KFunction primaryConstructor = KClasses.getPrimaryConstructor(JvmClassMappingKt.getKotlinClass(clazz));
if (primaryConstructor != null) {
@@ -462,8 +455,7 @@ public class SpringFactoriesLoader {
return null;
}
- public static T instantiate(Constructor constructor, Object[] args)
- throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ static T instantiate(Constructor constructor, Object[] args) throws Exception {
KFunction kotlinConstructor = ReflectJvmMapping.getKotlinFunction(constructor);
if (kotlinConstructor == null) {
return constructor.newInstance(args);
@@ -483,7 +475,7 @@ public class SpringFactoriesLoader {
private static Map convertArgs(Object[] args, List parameters) {
Map result = CollectionUtils.newHashMap(parameters.size());
Assert.isTrue(args.length <= parameters.size(),
- "Number of provided arguments should be less of equals than number of constructor parameters");
+ "Number of provided arguments should be less than or equal to the number of constructor parameters");
for (int i = 0; i < args.length; i++) {
if (!parameters.get(i).isOptional() || args[i] != null) {
result.put(parameters.get(i), args[i]);
@@ -552,12 +544,12 @@ public class SpringFactoriesLoader {
default ArgumentResolver and(ArgumentResolver argumentResolver) {
return from(type -> {
Object resolved = resolve(type);
- return (resolved != null) ? resolved : argumentResolver.resolve(type);
+ return (resolved != null ? resolved : argumentResolver.resolve(type));
});
}
/**
- * Factory method that returns a {@link ArgumentResolver} that always
+ * Factory method that returns an {@link ArgumentResolver} that always
* returns {@code null}.
* @return a new {@link ArgumentResolver} instance
*/
@@ -566,7 +558,7 @@ public class SpringFactoriesLoader {
}
/**
- * Factory method that can be used to create a {@link ArgumentResolver}
+ * Factory method that can be used to create an {@link ArgumentResolver}
* that resolves only the given type.
* @param the argument type
* @param type the argument type
@@ -578,7 +570,7 @@ public class SpringFactoriesLoader {
}
/**
- * Factory method that can be used to create a {@link ArgumentResolver}
+ * Factory method that can be used to create an {@link ArgumentResolver}
* that resolves only the given type.
* @param the argument type
* @param type the argument type
@@ -643,8 +635,8 @@ public class SpringFactoriesLoader {
}
/**
- * Return a new {@link FailureHandler} that handles
- * errors by throwing an exception.
+ * Return a new {@link FailureHandler} that handles errors by throwing an
+ * exception.
* @param exceptionFactory factory used to create the exception
* @return a new {@link FailureHandler} instance
*/
@@ -655,8 +647,8 @@ public class SpringFactoriesLoader {
}
/**
- * Return a new {@link FailureHandler} that handles
- * errors by logging trace messages.
+ * Return a new {@link FailureHandler} that handles errors by logging trace
+ * messages.
* @param logger the logger used to log message
* @return a new {@link FailureHandler} instance
*/
@@ -665,15 +657,15 @@ public class SpringFactoriesLoader {
}
/**
- * Return a new {@link FailureHandler} that handles
- * errors with using a standard formatted message.
+ * Return a new {@link FailureHandler} that handles errors using a standard
+ * formatted message.
* @param messageHandler the message handler used to handle the problem
* @return a new {@link FailureHandler} instance
*/
static FailureHandler handleMessage(BiConsumer, Throwable> messageHandler) {
return (factoryType, factoryImplementationName, failure) -> {
- Supplier message = () -> "Unable to instantiate factory class [" + factoryImplementationName +
- "] for factory type [" + factoryType.getName() + "]";
+ Supplier message = () -> "Unable to instantiate factory class [%s] for factory type [%s]"
+ .formatted(factoryImplementationName, factoryType.getName());
messageHandler.accept(message, failure);
};
}
diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoaderRuntimeHintsRegistrar.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoaderRuntimeHintsRegistrar.java
index 185d465cae2..1e0d3f38088 100644
--- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoaderRuntimeHintsRegistrar.java
+++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoaderRuntimeHintsRegistrar.java
@@ -41,11 +41,11 @@ import org.springframework.util.ClassUtils;
*/
class SpringFactoriesLoaderRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
- private static List RESOURCE_LOCATIONS = List
- .of(SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION);
+ private static List RESOURCE_LOCATIONS =
+ List.of(SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION);
- private static final Consumer HINT = builder -> builder
- .withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
+ private static final Consumer HINT = builder ->
+ builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
private final Log logger = LogFactory.getLog(SpringFactoriesLoaderRuntimeHintsRegistrar.class);
@@ -57,11 +57,10 @@ class SpringFactoriesLoaderRuntimeHintsRegistrar implements RuntimeHintsRegistra
}
}
- private void registerHints(RuntimeHints hints, ClassLoader classLoader,
- String resourceLocation) {
+ private void registerHints(RuntimeHints hints, ClassLoader classLoader, String resourceLocation) {
hints.resources().registerPattern(resourceLocation);
- Map> factories = SpringFactoriesLoader
- .loadFactoriesResource(classLoader, resourceLocation);
+ Map> factories =
+ SpringFactoriesLoader.loadFactoriesResource(classLoader, resourceLocation);
factories.forEach((factoryClassName, implementationClassNames) ->
registerHints(hints, classLoader, factoryClassName, implementationClassNames));
}
@@ -69,7 +68,7 @@ class SpringFactoriesLoaderRuntimeHintsRegistrar implements RuntimeHintsRegistra
private void registerHints(RuntimeHints hints, ClassLoader classLoader,
String factoryClassName, List implementationClassNames) {
Class> factoryClass = resolveClassName(classLoader, factoryClassName);
- if(factoryClass == null) {
+ if (factoryClass == null) {
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("Skipping factories for [%s]", factoryClassName));
}
@@ -83,7 +82,8 @@ class SpringFactoriesLoaderRuntimeHintsRegistrar implements RuntimeHintsRegistra
Class> implementationType = resolveClassName(classLoader, implementationClassName);
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("%s factory type [%s] and implementation [%s]",
- (implementationType != null) ? "Processing" : "Skipping", factoryClassName, implementationClassName));
+ (implementationType != null ? "Processing" : "Skipping"), factoryClassName,
+ implementationClassName));
}
if (implementationType != null) {
hints.reflection().registerType(implementationType, HINT);