/** * Get the names of the default {@link TestExecutionListener} classes for * this bootstrapper. * <p>The default implementation looks up all * {@code org.springframework.test.context.TestExecutionListener} entries * configured in all {@code META-INF/spring.factories} files on the classpath. * <p>This method is invoked by {@link #getDefaultTestExecutionListenerClasses()}. * @return an <em>unmodifiable</em> list of names of default {@code TestExecutionListener} * classes * @see SpringFactoriesLoader#loadFactoryNames */ protected List<String> getDefaultTestExecutionListenerClassNames() { List<String> classNames = SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, getClass().getClassLoader()); if (logger.isInfoEnabled()) { logger.info(String.format("Loaded default TestExecutionListener class names from location [%s]: %s", SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION, classNames)); } return Collections.unmodifiableList(classNames); }
/** * Load and instantiate the factory implementations of the given type from * {@value #FACTORIES_RESOURCE_LOCATION}, using the given class loader. * <p>The returned factories are sorted through {@link AnnotationAwareOrderComparator}. * <p>If a custom instantiation strategy is required, use {@link #loadFactoryNames} * to obtain all registered factory names. * @param factoryClass the interface or abstract class representing the factory * @param classLoader the ClassLoader to use for loading (can be {@code null} to use the default) * @throws IllegalArgumentException if any factory implementation class cannot * be loaded or if an error occurs while instantiating any factory * @see #loadFactoryNames */ public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) { Assert.notNull(factoryClass, "'factoryClass' must not be null"); ClassLoader classLoaderToUse = classLoader; if (classLoaderToUse == null) { classLoaderToUse = SpringFactoriesLoader.class.getClassLoader(); } List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse); if (logger.isTraceEnabled()) { logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames); } List<T> result = new ArrayList<>(factoryNames.size()); for (String factoryName : factoryNames) { result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse)); } AnnotationAwareOrderComparator.sort(result); return result; }
private List<FailureAnalyzer> loadFailureAnalyzers(ClassLoader classLoader) { List<String> analyzerNames = SpringFactoriesLoader .loadFactoryNames(FailureAnalyzer.class, classLoader); List<FailureAnalyzer> analyzers = new ArrayList<>(); for (String analyzerName : analyzerNames) { try { Constructor<?> constructor = ClassUtils.forName(analyzerName, classLoader) .getDeclaredConstructor(); ReflectionUtils.makeAccessible(constructor); analyzers.add((FailureAnalyzer) constructor.newInstance()); } catch (Throwable ex) { logger.trace("Failed to load " + analyzerName, ex); } } AnnotationAwareOrderComparator.sort(analyzers); return analyzers; }
/** * Load and instantiate the factory implementations of the given type from * {@value #FACTORIES_RESOURCE_LOCATION}, using the given class loader. * <p>The returned factories are sorted through {@link AnnotationAwareOrderComparator}. * <p>If a custom instantiation strategy is required, use {@link #loadFactoryNames} * to obtain all registered factory names. * @param factoryClass the interface or abstract class representing the factory * @param classLoader the ClassLoader to use for loading (can be {@code null} to use the default) * @throws IllegalArgumentException if any factory implementation class cannot * be loaded or if an error occurs while instantiating any factory * @see #loadFactoryNames */ public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) { Assert.notNull(factoryClass, "'factoryClass' must not be null"); ClassLoader classLoaderToUse = classLoader; if (classLoaderToUse == null) { classLoaderToUse = SpringFactoriesLoader.class.getClassLoader(); } List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse); if (logger.isTraceEnabled()) { logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames); } List<T> result = new ArrayList<>(factoryNames.size()); for (String factoryName : factoryNames) { result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse)); } AnnotationAwareOrderComparator.sort(result); return result; }
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); // Use names and ensure unique to protect against duplicates Set<String> names = new LinkedHashSet<>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
List<TemplateVariableProvider> getTemplateVariableProviders() { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Set<String> factories = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames( TemplateVariableProvider.class, Thread.currentThread().getContextClassLoader())); return factories.stream() .map(new Function<String, TemplateVariableProvider>() { @Override public TemplateVariableProvider apply(String name) { try { Class<TemplateVariableProvider> instanceClass = (Class<TemplateVariableProvider>) ClassUtils.forName(name, classLoader); return applicationContext.getBean(instanceClass); } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } } }).collect(Collectors.toList()); } }
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates List<String> names = new ArrayList<>(SpringFactoriesLoader .loadFactoryNames(BootstrapConfiguration.class, classLoader)); names.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray( environment.getProperty("spring.cloud.bootstrap.sources", "")))); List<OrderedAnnotatedElement> elements = new ArrayList<>(); for (String name : names) { try { elements.add(new OrderedAnnotatedElement(metadataReaderFactory, name)); } catch (IOException e) { continue; } } AnnotationAwareOrderComparator.sort(elements); String[] classNames = elements.stream() .map(e -> e.name) .toArray(String[]::new); return classNames; }
@Override public String[] selectImports(AnnotationMetadata metadata) { if (!isEnabled()) { return new String[0]; } AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(this.annotationClass.getName(), true)); Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is " + metadata.getClassName() + " annotated with @" + getSimpleName() + "?"); // Find all possible auto configuration classes, filtering duplicates List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader .loadFactoryNames(this.annotationClass, this.beanClassLoader))); if (factories.isEmpty() && !hasDefaultFactory()) { throw new IllegalStateException("Annotation @" + getSimpleName() + " found, but there are no implementations. Did you forget to include a starter?"); } if (factories.size() > 1) { // there should only ever be one DiscoveryClient, but there might be more than // one factory log.warn("More than one implementation " + "of @" + getSimpleName() + " (now relying on @Conditionals to pick one): " + factories); } return factories.toArray(new String[factories.size()]); }
protected List<String> loadFactoryNames() { return SpringFactoriesLoader .loadFactoryNames(ManagementContextConfiguration.class, this.classLoader); }
@Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { List<String> result = new ArrayList<>(); result.add(EventPublicationConfiguration.class.getName()); result.addAll(loadFactoryNames(EventPublicationConfigurationExtension.class, resourceLoader.getClassLoader())); result.addAll(loadFactoryNames(EventSerializationConfigurationExtension.class, resourceLoader.getClassLoader())); return result.toArray(new String[result.size()]); } }
@Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { List<String> imports = new ArrayList<>(); imports.add(ProjectingArgumentResolverRegistrar.class.getName()); imports.add(resourceLoader// .filter(it -> ClassUtils.isPresent("org.springframework.hateoas.Link", it))// .map(it -> HateoasAwareSpringDataWebConfiguration.class.getName())// .orElseGet(() -> SpringDataWebConfiguration.class.getName())); resourceLoader// .filter(it -> ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", it))// .map(it -> SpringFactoriesLoader.loadFactoryNames(SpringDataJacksonModules.class, it))// .ifPresent(it -> imports.addAll(it)); return imports.toArray(new String[imports.size()]); } }
/** * Get the names of the default {@link TestExecutionListener} classes for * this bootstrapper. * <p>The default implementation looks up all * {@code org.springframework.test.context.TestExecutionListener} entries * configured in all {@code META-INF/spring.factories} files on the classpath. * <p>This method is invoked by {@link #getDefaultTestExecutionListenerClasses()}. * @return an <em>unmodifiable</em> list of names of default {@code TestExecutionListener} * classes * @see SpringFactoriesLoader#loadFactoryNames */ protected List<String> getDefaultTestExecutionListenerClassNames() { List<String> classNames = SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, getClass().getClassLoader()); if (logger.isInfoEnabled()) { logger.info(String.format("Loaded default TestExecutionListener class names from location [%s]: %s", SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION, classNames)); } return Collections.unmodifiableList(classNames); }
/** * Get the names of the default {@link TestExecutionListener} classes for * this bootstrapper. * <p>The default implementation looks up all * {@code org.springframework.test.context.TestExecutionListener} entries * configured in all {@code META-INF/spring.factories} files on the classpath. * <p>This method is invoked by {@link #getDefaultTestExecutionListenerClasses()}. * @return an <em>unmodifiable</em> list of names of default {@code TestExecutionListener} * classes * @see SpringFactoriesLoader#loadFactoryNames */ protected List<String> getDefaultTestExecutionListenerClassNames() { List<String> classNames = SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, getClass().getClassLoader()); if (logger.isInfoEnabled()) { logger.info(String.format("Loaded default TestExecutionListener class names from location [%s]: %s", SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION, classNames)); } return Collections.unmodifiableList(classNames); }
/** * Scans {@code repository.support} packages for implementations of {@link RepositoryFactorySupport}. Finding more * than a single type is considered a multi-store configuration scenario which will trigger stricter repository * scanning. * * @return */ private boolean multipleStoresDetected() { boolean multipleModulesFound = SpringFactoriesLoader .loadFactoryNames(RepositoryFactorySupport.class, resourceLoader.getClassLoader()).size() > 1; if (multipleModulesFound) { LOG.info(MULTIPLE_MODULES); } return multipleModulesFound; }
private Collection<? extends T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { 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)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Set<String> names = new LinkedHashSet<>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates List<String> names = new ArrayList<>(SpringFactoriesLoader .loadFactoryNames(BootstrapConfiguration.class, classLoader)); names.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray( environment.getProperty("spring.cloud.bootstrap.sources", "")))); List<OrderedAnnotatedElement> elements = new ArrayList<>(); for (String name : names) { try { elements.add(new OrderedAnnotatedElement(metadataReaderFactory, name)); } catch (IOException e) { continue; } } AnnotationAwareOrderComparator.sort(elements); String[] classNames = elements.stream() .map(e -> e.name) .toArray(String[]::new); return classNames; }
@Override public void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event) { // 获取当前 ClassLoader ClassLoader classLoader = event.getClass().getClassLoader(); // 候选的自动装配类名单 List<String> candidates = SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader); // 实际的自动装配类名单 List<String> configurations = event.getCandidateConfigurations(); // 排除的自动装配类名单 Set<String> exclusions = event.getExclusions(); // 输出各自数量 System.out.printf("自动装配类名单 - 候选数量:%d,实际数量:%d,排除数量:%s\n", candidates.size(), configurations.size(), exclusions.size()); // 输出实际和排除的自动装配类名单 System.out.println("实际的自动装配类名单:"); event.getCandidateConfigurations().forEach(System.out::println); System.out.println("排除的自动装配类名单:"); event.getExclusions().forEach(System.out::println); } }
@Override public String[] selectImports(AnnotationMetadata metadata) { if (!isEnabled()) { return new String[0]; } AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(this.annotationClass.getName(), true)); Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is " + metadata.getClassName() + " annotated with @" + getSimpleName() + "?"); // Find all possible auto configuration classes, filtering duplicates List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(this.annotationClass, this.beanClassLoader))); if (factories.isEmpty() && !hasDefaultFactory()) { throw new IllegalStateException("Annotation @" + getSimpleName() + " found, but there are no implementations. Did you forget to include a starter?"); } if (factories.size() > 1) { // there should only ever be one DiscoveryClient, but there might be more than one factory LOG.warn("More than one implementation " + "of @" + getSimpleName() + " (now relying on @Conditionals to pick one): " + factories); } return factories.toArray(new String[factories.size()]); }
@Override public String[] selectImports(AnnotationMetadata metadata) { if (!isEnabled()) { return new String[0]; } AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(this.annotationClass.getName(), true)); Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is " + metadata.getClassName() + " annotated with @" + getSimpleName() + "?"); // Find all possible auto configuration classes, filtering duplicates List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader .loadFactoryNames(this.annotationClass, this.beanClassLoader))); if (factories.isEmpty() && !hasDefaultFactory()) { throw new IllegalStateException("Annotation @" + getSimpleName() + " found, but there are no implementations. Did you forget to include a starter?"); } if (factories.size() > 1) { // there should only ever be one DiscoveryClient, but there might be more than // one factory log.warn("More than one implementation " + "of @" + getSimpleName() + " (now relying on @Conditionals to pick one): " + factories); } return factories.toArray(new String[factories.size()]); }