Skip to content

Commit

Permalink
feat(spring): use getBeansOfTypes() instead of manual search the fact…
Browse files Browse the repository at this point in the history
…ories

APIM-7022
  • Loading branch information
michel-barret committed Oct 8, 2024
1 parent d532e55 commit 0516a07
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
* @author David BRASSELY (david.brassely at graviteesource.com)
Expand All @@ -50,41 +48,18 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
protected Collection<? extends T> getFactoriesInstances() {
if (factories == null) {
logger.debug("Loading instances for type {}", getObjectType().getName());
factories = getSpringFactoriesInstances(applicationContext, getObjectType());
Class<T> type = getObjectType();
factories = createSpringFactoriesInstances(applicationContext, type);
} else {
logger.debug("Instances for type {} already loaded. Skipping...", getObjectType().getName());
}

return factories;
}

private Collection<? extends T> getSpringFactoriesInstances(ApplicationContext applicationContext, Class<T> type) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(type, classLoader)
);
return createSpringFactoriesInstances(applicationContext, type, classLoader, names);
}

// @VisibleForTesting
@SuppressWarnings("unchecked")
static <U> List<U> createSpringFactoriesInstances(
ApplicationContext applicationContext,
Class<U> type,
ClassLoader classLoader,
Set<String> names
) {
List<U> instances = new ArrayList<>(names.size());
for (String name : names) {
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
instances.add((U) applicationContext.getBean(instanceClass));
} catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
static <U> List<U> createSpringFactoriesInstances(ApplicationContext applicationContext, Class<U> type) {
var instances = new ArrayList<>(applicationContext.getBeansOfType(type).values());
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -102,17 +101,7 @@ void createSpringFactoriesInstances() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringFactoriesLoaderTest.class);

// When
List<AService> svc = SpringFactoriesLoader.createSpringFactoriesInstances(
ctx,
AService.class,
SpringFactoriesLoaderTest.class.getClassLoader(),
Set.of(
MyService.class.getCanonicalName(),
MyAnotherService.class.getCanonicalName(),
MyYetAnotherService.class.getCanonicalName(),
MyYetYetAnotherService.class.getCanonicalName()
)
);
List<AService> svc = SpringFactoriesLoader.createSpringFactoriesInstances(ctx, AService.class);

// Then
assertThat(svc).hasSize(4);
Expand Down

0 comments on commit 0516a07

Please sign in to comment.