io.gravitee.common.spring.factory.SpringFactoriesLoader Maven / Gradle / Ivy
/*
* Copyright © 2015 The Gravitee team (http://gravitee.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.gravitee.common.spring.factory;
import java.lang.reflect.Constructor;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* @author David BRASSELY (david.brassely at graviteesource.com)
* @author GraviteeSource Team
*/
public abstract class SpringFactoriesLoader implements ApplicationContextAware {
/**
* Logger.
*/
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected ApplicationContext applicationContext;
private Collection extends T> factories;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
protected abstract Class getObjectType();
protected Collection extends T> getFactoriesInstances() {
if (factories == null) {
logger.debug("Loading instances for type {}", getObjectType().getName());
factories = getSpringFactoriesInstances(getObjectType(), new Class>[] {});
} else {
logger.debug("Instances for type {} already loaded. Skipping...", getObjectType().getName());
}
return factories;
}
private Collection extends T> getSpringFactoriesInstances(Class type, Class>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set names = new LinkedHashSet<>(
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(type, classLoader)
);
List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
@SuppressWarnings("unchecked")
private List createSpringFactoriesInstances(
Class type,
Class>[] parameterTypes,
ClassLoader classLoader,
Object[] args,
Set names
) {
List instances = new ArrayList<>(names.size());
for (String name : names) {
try {
Class> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
((AbstractApplicationContext) applicationContext).getBeanFactory().autowireBean(instance);
if (instance instanceof ApplicationContextAware) {
((ApplicationContextAware) instance).setApplicationContext(applicationContext);
}
instances.add(instance);
} catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy