io.seata.common.loader.EnhancedServiceLoader Maven / Gradle / Ivy
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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.seata.common.loader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import io.seata.common.Constants;
import io.seata.common.executor.Initialize;
import io.seata.common.util.CollectionUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The type Enhanced service loader.
*
* @author slievrly
*/
public class EnhancedServiceLoader {
/**
* Specify classLoader to load the service provider
*
* @param the type parameter
* @param service the service
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service, ClassLoader loader) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(loader);
}
/**
* load service provider
*
* @param the type parameter
* @param service the service
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(findClassLoader());
}
/**
* load service provider
*
* @param the type parameter
* @param service the service
* @param activateName the activate name
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service, String activateName) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, findClassLoader());
}
/**
* Specify classLoader to load the service provider
*
* @param the type parameter
* @param service the service
* @param activateName the activate name
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service, String activateName, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, loader);
}
/**
* Load s.
*
* @param the type parameter
* @param service the service
* @param activateName the activate name
* @param args the args
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service, String activateName, Object[] args)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, args, findClassLoader());
}
/**
* Load s.
*
* @param the type parameter
* @param service the service
* @param activateName the activate name
* @param argsType the args type
* @param args the args
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static S load(Class service, String activateName, Class[] argsType, Object[] args)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, argsType, args, findClassLoader());
}
/**
* get all implements
*
* @param the type parameter
* @param service the service
* @return list list
*/
public static List loadAll(Class service) {
return InnerEnhancedServiceLoader.getServiceLoader(service).loadAll(findClassLoader());
}
/**
* get all implements
*
* @param the type parameter
* @param service the service
* @param argsType the args type
* @param args the args
* @return list list
*/
public static List loadAll(Class service, Class[] argsType, Object[] args) {
return InnerEnhancedServiceLoader.getServiceLoader(service).loadAll(argsType, args, findClassLoader());
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param the type parameter
* @param service the service
* @return all extension class
*/
@SuppressWarnings("rawtypes")
static List getAllExtensionClass(Class service) {
return InnerEnhancedServiceLoader.getServiceLoader(service).getAllExtensionClass(findClassLoader());
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param the type parameter
* @param service the service
* @param loader the loader
* @return all extension class
*/
@SuppressWarnings("rawtypes")
static List getAllExtensionClass(Class service, ClassLoader loader) {
return InnerEnhancedServiceLoader.getServiceLoader(service).getAllExtensionClass(loader);
}
/**
* Cannot use TCCL, in the pandora container will cause the class in the plugin not to be loaded
*
* @return
*/
private static ClassLoader findClassLoader() {
return EnhancedServiceLoader.class.getClassLoader();
}
private static class InnerEnhancedServiceLoader {
private static final Logger LOGGER = LoggerFactory.getLogger(InnerEnhancedServiceLoader.class);
private static final String SERVICES_DIRECTORY = "META-INF/services/";
private static final String SEATA_DIRECTORY = "META-INF/seata/";
private static final ConcurrentMap, InnerEnhancedServiceLoader>> SERVICE_LOADERS =
new ConcurrentHashMap<>();
private final Class type;
private final Holder> definitionsHolder = new Holder<>();
private final ConcurrentMap> definitionToInstanceMap =
new ConcurrentHashMap<>();
private final ConcurrentMap> nameToDefinitionsMap = new ConcurrentHashMap<>();
private final ConcurrentMap, ExtensionDefinition> classToDefinitionMap = new ConcurrentHashMap<>();
private InnerEnhancedServiceLoader(Class type) {
this.type = type;
}
/**
* Get the ServiceLoader for the specified Class
*
* @param type the type of the extension point
* @param the type
* @return the service loader
*/
private static InnerEnhancedServiceLoader getServiceLoader(Class type) {
if (type == null) {
throw new IllegalArgumentException("Enhanced Service type == null");
}
return (InnerEnhancedServiceLoader)CollectionUtils.computeIfAbsent(SERVICE_LOADERS, type,
key -> new InnerEnhancedServiceLoader<>(type));
}
/**
* Specify classLoader to load the service provider
*
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(ClassLoader loader) throws EnhancedServiceNotFoundException {
return loadExtension(loader, null, null);
}
/**
* Specify classLoader to load the service provider
*
* @param activateName the activate name
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return loadExtension(activateName, loader, null, null);
}
/**
* Load s.
*
* @param activateName the activate name
* @param args the args
* @param loader the loader
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, Object[] args, ClassLoader loader)
throws EnhancedServiceNotFoundException {
Class[] argsType = null;
if (args != null && args.length > 0) {
argsType = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argsType[i] = args[i].getClass();
}
}
return loadExtension(activateName, loader, argsType, args);
}
/**
* Load s.
*
* @param activateName the activate name
* @param argsType the args type
* @param args the args
* @param loader the class loader
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, Class[] argsType, Object[] args, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return loadExtension(activateName, loader, argsType, args);
}
/**
* get all implements
* @param loader the class loader
*
* @return list list
*/
private List loadAll(ClassLoader loader) {
return loadAll(null, null, loader);
}
/**
* get all implements
*
* @param argsType the args type
* @param args the args
* @return list list
*/
private List loadAll(Class[] argsType, Object[] args, ClassLoader loader) {
List allInstances = new ArrayList<>();
List allClazzs = getAllExtensionClass(loader);
if (CollectionUtils.isEmpty(allClazzs)) {
return allInstances;
}
try {
for (Class clazz : allClazzs) {
ExtensionDefinition definition = classToDefinitionMap.get(clazz);
allInstances.add(getExtensionInstance(definition, loader, argsType, args));
}
} catch (Throwable t) {
throw new EnhancedServiceNotFoundException(t);
}
return allInstances;
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param loader the loader
* @return all extension class
*/
@SuppressWarnings("rawtypes")
private List getAllExtensionClass(ClassLoader loader) {
return loadAllExtensionClass(loader);
}
@SuppressWarnings("rawtypes")
private S loadExtension(ClassLoader loader, Class[] argTypes,
Object[] args) {
try {
loadAllExtensionClass(loader);
ExtensionDefinition defaultExtensionDefinition = getDefaultExtensionDefinition();
return getExtensionInstance(defaultExtensionDefinition, loader, argTypes, args);
} catch (Throwable e) {
if (e instanceof EnhancedServiceNotFoundException) {
throw (EnhancedServiceNotFoundException)e;
} else {
throw new EnhancedServiceNotFoundException(
"not found service provider for : " + type.getName() + " caused by " + ExceptionUtils
.getFullStackTrace(e));
}
}
}
@SuppressWarnings("rawtypes")
private S loadExtension(String activateName, ClassLoader loader, Class[] argTypes,
Object[] args) {
if (io.seata.common.util.StringUtils.isEmpty(activateName)) {
throw new IllegalArgumentException("the name of service provider for [" + type.getName() + "] name is null");
}
try {
loadAllExtensionClass(loader);
ExtensionDefinition cachedExtensionDefinition = getCachedExtensionDefinition(activateName);
return getExtensionInstance(cachedExtensionDefinition, loader, argTypes, args);
} catch (Throwable e) {
if (e instanceof EnhancedServiceNotFoundException) {
throw (EnhancedServiceNotFoundException)e;
} else {
throw new EnhancedServiceNotFoundException(
"not found service provider for : " + type.getName() + " caused by " + ExceptionUtils
.getFullStackTrace(e));
}
}
}
private S getExtensionInstance(ExtensionDefinition definition, ClassLoader loader, Class[] argTypes,
Object[] args) {
if (definition == null) {
throw new EnhancedServiceNotFoundException("not found service provider for : " + type.getName());
}
if (Scope.SINGLETON.equals(definition.getScope())) {
Holder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy