增加InstanceProvider,统一Provider接口

This commit is contained in:
Redkale
2022-11-25 13:34:52 +08:00
parent 949498f3a7
commit 7621c4bdc3
14 changed files with 147 additions and 92 deletions

View File

@@ -124,8 +124,8 @@
如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。 如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。
如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。 如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。
先加载子节点property再加载load文件 最后加载agent的实现子类。 先加载子节点property再加载load文件 最后加载agent的实现子类。
agent: 实现类名必须是org.redkale.boot.PropertiesAgent的子类
load: 加载文件,多个用;隔开。 load: 加载文件,多个用;隔开。
其他属性: 供org.redkale.boot.PropertiesAgentProvider使用判断
默认置入的system.property.的有: 默认置入的system.property.的有:
System.setProperty("redkale.net.transport.poolmaxconns", "100"); System.setProperty("redkale.net.transport.poolmaxconns", "100");
System.setProperty("redkale.net.transport.pinginterval", "30"); System.setProperty("redkale.net.transport.pinginterval", "30");
@@ -138,7 +138,7 @@
<properties>节点下也可包含非<property>节点. <properties>节点下也可包含非<property>节点.
非<property>其节点可以通过@Resource(name="properties.xxxxxx")进行注入, 被注解的字段类型只能是AnyValue、AnyValue[] 非<property>其节点可以通过@Resource(name="properties.xxxxxx")进行注入, 被注解的字段类型只能是AnyValue、AnyValue[]
--> -->
<properties load="config.properties" agent=""> <properties load="config.properties">
<property name="system.property.yyyy" value="YYYYYY"/> <property name="system.property.yyyy" value="YYYYYY"/>
<property name="xxxxxx" value="XXXXXXXX"/> <property name="xxxxxx" value="XXXXXXXX"/>
<property name="xxxxxx" value="XXXXXXXX"/> <property name="xxxxxx" value="XXXXXXXX"/>

View File

@@ -494,11 +494,10 @@ public final class Application {
Iterator<ClusterAgentProvider> it = ServiceLoader.load(ClusterAgentProvider.class, classLoader).iterator(); Iterator<ClusterAgentProvider> it = ServiceLoader.load(ClusterAgentProvider.class, classLoader).iterator();
RedkaleClassLoader.putServiceLoader(ClusterAgentProvider.class); RedkaleClassLoader.putServiceLoader(ClusterAgentProvider.class);
while (it.hasNext()) { while (it.hasNext()) {
ClusterAgentProvider agent = it.next(); ClusterAgentProvider provider = it.next();
if (agent != null) RedkaleClassLoader.putReflectionPublicConstructors(agent.getClass(), agent.getClass().getName()); //loader class if (provider != null) RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName()); //loader class
if (agent != null && agent.acceptsConf(clusterConf)) { if (provider != null && provider.acceptsConf(clusterConf)) {
RedkaleClassLoader.putReflectionPublicConstructors(agent.getClass(), agent.agentClass().getName()); //agent class cluster = provider.createInstance();
cluster = agent.agentClass().getConstructor().newInstance();
cluster.setConfig(clusterConf); cluster.setConfig(clusterConf);
break; break;
} }
@@ -550,11 +549,10 @@ public final class Application {
Iterator<MessageAgentProvider> it = ServiceLoader.load(MessageAgentProvider.class, classLoader).iterator(); Iterator<MessageAgentProvider> it = ServiceLoader.load(MessageAgentProvider.class, classLoader).iterator();
RedkaleClassLoader.putServiceLoader(MessageAgentProvider.class); RedkaleClassLoader.putServiceLoader(MessageAgentProvider.class);
while (it.hasNext()) { while (it.hasNext()) {
MessageAgentProvider messageAgent = it.next(); MessageAgentProvider provider = it.next();
if (messageAgent != null) RedkaleClassLoader.putReflectionPublicConstructors(messageAgent.getClass(), messageAgent.getClass().getName()); //loader class if (provider != null) RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName()); //loader class
if (messageAgent != null && messageAgent.acceptsConf(mqConf)) { if (provider != null && provider.acceptsConf(mqConf)) {
RedkaleClassLoader.putReflectionPublicConstructors(messageAgent.getClass(), messageAgent.agentClass().getName()); //agent class mqs[i] = provider.createInstance();
mqs[i] = messageAgent.agentClass().getConstructor().newInstance();
mqs[i].setConfig(mqConf); mqs[i].setConfig(mqConf);
break; break;
} }
@@ -797,19 +795,26 @@ public final class Application {
} }
} }
String agent = propertiesConf.getValue("agent"); if ((dfloads == null && propertiesConf.getStringEntrys().length > 0) || (dfloads != null && propertiesConf.getStringEntrys().length > 1)) {
if (agent != null && !agent.isEmpty() && !PropertiesAgent.class.getName().equals(agent)) { Iterator<PropertiesAgentProvider> it = ServiceLoader.load(PropertiesAgentProvider.class, classLoader).iterator();
Class<PropertiesAgent> clazz = (Class) classLoader.loadClass(agent); RedkaleClassLoader.putServiceLoader(PropertiesAgentProvider.class);
if (!PropertiesAgent.class.isAssignableFrom(clazz)) { List<PropertiesAgentProvider> providers = new ArrayList<>();
throw new RuntimeException("PropertiesAgent class (" + agent + ") is not " + PropertiesAgent.class.getName() + " impl class"); while (it.hasNext()) {
PropertiesAgentProvider provider = it.next();
if (provider != null) RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName()); //loader class
if (provider != null && provider.acceptsConf(propertiesConf)) {
providers.add(provider);
}
} }
RedkaleClassLoader.putReflectionPublicConstructors(clazz, clazz.getName()); for (PropertiesAgentProvider provider : InstanceProvider.sort(providers)) {
this.propertiesAgent = clazz.getConstructor().newInstance(); this.propertiesAgent = provider.createInstance();
this.resourceFactory.inject(this.propertiesAgent); this.resourceFactory.inject(this.propertiesAgent);
if (compileMode) { if (compileMode) {
this.propertiesAgent.compile(propertiesConf); this.propertiesAgent.compile(propertiesConf);
} else { } else {
this.propertiesAgent.init(resourceFactory, appProperties, propertiesConf); this.propertiesAgent.init(resourceFactory, appProperties, propertiesConf);
}
break;
} }
} }
} }
@@ -1009,39 +1014,34 @@ public final class Application {
} }
String classval = sourceConf.getValue("type"); String classval = sourceConf.getValue("type");
try { try {
Class sourceType = null; CacheSource source = null;
if (classval == null || classval.isEmpty()) { if (classval == null || classval.isEmpty()) {
RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class); RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
List<CacheSourceProvider> providers = new ArrayList<>(); List<CacheSourceProvider> providers = new ArrayList<>();
Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator(); Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) { while (it.hasNext()) {
CacheSourceProvider s = it.next(); CacheSourceProvider provider = it.next();
if (s != null) RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName()); if (provider != null) RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) { if (provider != null && provider.acceptsConf(sourceConf)) {
providers.add(s); providers.add(provider);
} }
} }
Collections.sort(providers, (a, b) -> { for (CacheSourceProvider provider : InstanceProvider.sort(providers)) {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class); source = provider.createInstance();
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class); if (source != null) break;
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (CacheSourceProvider provider : providers) {
sourceType = provider.sourceClass();
if (sourceType != null) break;
} }
if (sourceType == null) { if (source == null) {
if (CacheMemorySource.acceptsConf(sourceConf)) { if (CacheMemorySource.acceptsConf(sourceConf)) {
sourceType = CacheMemorySource.class; source = new CacheMemorySource(sourceName);
} }
} }
} else { } else {
sourceType = serverClassLoader.loadClass(classval); Class sourceType = serverClassLoader.loadClass(classval);
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
source = (CacheSource) sourceType.getConstructor().newInstance();
} }
if (sourceType == null) throw new RuntimeException("Not found CacheSourceProvider for config=" + sourceConf); if (source == null) throw new RuntimeException("Not found CacheSourceProvider for config=" + sourceConf);
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
CacheSource source = sourceType == CacheMemorySource.class ? new CacheMemorySource(sourceName) : (CacheSource) sourceType.getConstructor().newInstance();
cacheSources.add(source); cacheSources.add(source);
resourceFactory.register(sourceName, source); resourceFactory.register(sourceName, source);
resourceFactory.inject(sourceName, source); resourceFactory.inject(sourceName, source);
@@ -1070,45 +1070,40 @@ public final class Application {
} }
String classval = sourceConf.getValue("type"); String classval = sourceConf.getValue("type");
try { try {
Class sourceType = null; DataSource source = null;
if (classval == null || classval.isEmpty()) { if (classval == null || classval.isEmpty()) {
if (DataJdbcSource.acceptsConf(sourceConf)) { if (DataJdbcSource.acceptsConf(sourceConf)) {
sourceType = DataJdbcSource.class; source = new DataJdbcSource();
} else { } else {
RedkaleClassLoader.putServiceLoader(DataSourceProvider.class); RedkaleClassLoader.putServiceLoader(DataSourceProvider.class);
List<DataSourceProvider> providers = new ArrayList<>(); List<DataSourceProvider> providers = new ArrayList<>();
Iterator<DataSourceProvider> it = ServiceLoader.load(DataSourceProvider.class, serverClassLoader).iterator(); Iterator<DataSourceProvider> it = ServiceLoader.load(DataSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) { while (it.hasNext()) {
DataSourceProvider s = it.next(); DataSourceProvider provider = it.next();
if (s != null) RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName()); if (provider != null) RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) { if (provider != null && provider.acceptsConf(sourceConf)) {
providers.add(s); providers.add(provider);
} }
} }
Collections.sort(providers, (a, b) -> { for (DataSourceProvider provider : InstanceProvider.sort(providers)) {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class); source = provider.createInstance();
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class); if (source != null) break;
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (DataSourceProvider provider : providers) {
sourceType = provider.sourceClass();
if (sourceType != null) break;
} }
if (sourceType == null) { if (source == null) {
if (DataMemorySource.acceptsConf(sourceConf)) { if (DataMemorySource.acceptsConf(sourceConf)) {
sourceType = DataMemorySource.class; source = new DataMemorySource(sourceName);
} }
} }
} }
} else { } else {
sourceType = serverClassLoader.loadClass(classval); Class sourceType = serverClassLoader.loadClass(classval);
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
source = (DataSource) sourceType.getConstructor().newInstance();
} }
if (sourceType == null) throw new RuntimeException("Not found DataSourceProvider for config=" + sourceConf); if (source == null) throw new RuntimeException("Not found DataSourceProvider for config=" + sourceConf);
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
DataSource source = sourceType == DataMemorySource.class ? new DataMemorySource(sourceName) : (DataSource) sourceType.getConstructor().newInstance();
dataSources.add(source); dataSources.add(source);
if (sourceType == DataMemorySource.class && DataMemorySource.isSearchType(sourceConf)) { if (source instanceof DataMemorySource && DataMemorySource.isSearchType(sourceConf)) {
resourceFactory.register(sourceName, SearchSource.class, source); resourceFactory.register(sourceName, SearchSource.class, source);
} else { } else {
resourceFactory.register(sourceName, source); resourceFactory.register(sourceName, source);

View File

@@ -15,6 +15,7 @@ import java.net.*;
import java.nio.file.*; import java.nio.file.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.*; import java.util.function.*;
import java.util.logging.*; import java.util.logging.*;
import javax.annotation.*; import javax.annotation.*;
@@ -357,6 +358,7 @@ public abstract class NodeServer {
ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory; ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory;
final ResourceFactory appResourceFactory = application.getResourceFactory(); final ResourceFactory appResourceFactory = application.getResourceFactory();
final TransportFactory appSncpTransFactory = application.getSncpTransportFactory(); final TransportFactory appSncpTransFactory = application.getSncpTransportFactory();
final AtomicInteger serviceCount = new AtomicInteger();
for (FilterEntry<? extends Service> entry : entrys) { //service实现类 for (FilterEntry<? extends Service> entry : entrys) { //service实现类
final Class<? extends Service> serviceImplClass = entry.getType(); final Class<? extends Service> serviceImplClass = entry.getType();
if (Modifier.isFinal(serviceImplClass.getModifiers())) continue; //修饰final的类跳过 if (Modifier.isFinal(serviceImplClass.getModifiers())) continue; //修饰final的类跳过
@@ -422,6 +424,7 @@ public abstract class NodeServer {
interceptorServices.add(service); interceptorServices.add(service);
if (consumer != null) consumer.accept(agent, service); if (consumer != null) consumer.accept(agent, service);
} }
serviceCount.incrementAndGet();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
throw ex; throw ex;
} catch (Exception e) { } catch (Exception e) {
@@ -502,7 +505,7 @@ public abstract class NodeServer {
for (String s : wlist) { for (String s : wlist) {
sb.append(s); sb.append(s);
} }
sb.append(localThreadName).append("All Services load cost ").append(System.currentTimeMillis() - starts).append(" ms" + LINE_SEPARATOR); sb.append(localThreadName).append("All " + localServices.size() + " Services load cost ").append(System.currentTimeMillis() - starts).append(" ms");
} }
if (sb != null && preinite > 10) sb.append(localThreadName).append(ClusterAgent.class.getSimpleName()).append(" register ").append(preinite).append(" ms" + LINE_SEPARATOR); if (sb != null && preinite > 10) sb.append(localThreadName).append(ClusterAgent.class.getSimpleName()).append(" register ").append(preinite).append(" ms" + LINE_SEPARATOR);
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString()); if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());

View File

@@ -3,6 +3,7 @@
package org.redkale.boot; package org.redkale.boot;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Logger;
import org.redkale.util.*; import org.redkale.util.*;
/** /**
@@ -17,11 +18,9 @@ import org.redkale.util.*;
*/ */
public abstract class PropertiesAgent { public abstract class PropertiesAgent {
public static final String PROP_KEY_URL = "url";
public static final String PROP_KEY_NAMESPACE = "namespace"; public static final String PROP_KEY_NAMESPACE = "namespace";
public static final String PROP_NAMESPACE_APPLICATION = "application"; protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
/** /**
* 编译时进行的操作 * 编译时进行的操作
@@ -31,6 +30,15 @@ public abstract class PropertiesAgent {
public void compile(AnyValue conf) { public void compile(AnyValue conf) {
} }
/**
* ServiceLoader时判断配置是否符合当前实现类
*
* @param config 节点配置
*
* @return boolean
*/
public abstract boolean acceptsConf(AnyValue config);
/** /**
* 初始化配置源配置项需要写入appProperties并监听配置项的变化 * 初始化配置源配置项需要写入appProperties并监听配置项的变化
* *

View File

@@ -0,0 +1,19 @@
/*
*/
package org.redkale.boot;
import org.redkale.util.*;
/**
* 自定义的PropertiesAgent加载器
*
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface PropertiesAgentProvider extends InstanceProvider<PropertiesAgent> {
}

View File

@@ -86,7 +86,13 @@ public abstract class ClusterAgent {
public void destroy(AnyValue config) { public void destroy(AnyValue config) {
} }
//ServiceLoader时判断配置是否符合当前实现类 /**
* ServiceLoader时判断配置是否符合当前实现类
*
* @param config 节点配置
*
* @return boolean
*/
public abstract boolean acceptsConf(AnyValue config); public abstract boolean acceptsConf(AnyValue config);
public boolean containsProtocol(String protocol) { public boolean containsProtocol(String protocol) {

View File

@@ -5,7 +5,7 @@
*/ */
package org.redkale.cluster; package org.redkale.cluster;
import org.redkale.util.AnyValue; import org.redkale.util.*;
/** /**
* 自定义的ClusterAgent加载器 * 自定义的ClusterAgent加载器
@@ -17,9 +17,6 @@ import org.redkale.util.AnyValue;
* @author zhangjx * @author zhangjx
* @since 2.5.0 * @since 2.5.0
*/ */
public interface ClusterAgentProvider { public interface ClusterAgentProvider extends InstanceProvider<ClusterAgent> {
public boolean acceptsConf(AnyValue config);
public Class<? extends ClusterAgent> agentClass();
} }

View File

@@ -531,8 +531,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
} }
if (coder == null) { if (coder == null) {
try { try {
coder = (SimpledCoder) clazz1.getConstructor().newInstance();
RedkaleClassLoader.putReflectionPublicConstructors(clazz1, clazz1.getName()); RedkaleClassLoader.putReflectionPublicConstructors(clazz1, clazz1.getName());
coder = (SimpledCoder) clazz1.getConstructor().newInstance();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
continue; continue;

View File

@@ -5,7 +5,7 @@
*/ */
package org.redkale.mq; package org.redkale.mq;
import org.redkale.util.AnyValue; import org.redkale.util.*;
/** /**
* 自定义的MessageAgent加载器 * 自定义的MessageAgent加载器
@@ -17,9 +17,6 @@ import org.redkale.util.AnyValue;
* @author zhangjx * @author zhangjx
* @since 2.5.0 * @since 2.5.0
*/ */
public interface MessageAgentProvider { public interface MessageAgentProvider extends InstanceProvider<MessageAgent> {
public boolean acceptsConf(AnyValue config);
public Class<? extends MessageAgent> agentClass();
} }

View File

@@ -57,10 +57,12 @@ public class SSLBuilder {
Provider jsseProvider = null; Provider jsseProvider = null;
if (sslProviderImpl != null) { if (sslProviderImpl != null) {
Class<Provider> providerClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(sslProviderImpl); Class<Provider> providerClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(sslProviderImpl);
RedkaleClassLoader.putReflectionPublicConstructors(providerClass, providerClass.getName());
sslProvider = providerClass.getConstructor().newInstance(); sslProvider = providerClass.getConstructor().newInstance();
} }
if (jsseProviderImpl != null) { if (jsseProviderImpl != null) {
Class<Provider> providerClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(jsseProviderImpl); Class<Provider> providerClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(jsseProviderImpl);
RedkaleClassLoader.putReflectionPublicConstructors(providerClass, providerClass.getName());
jsseProvider = providerClass.getConstructor().newInstance(); jsseProvider = providerClass.getConstructor().newInstance();
} }
@@ -126,7 +128,7 @@ public class SSLBuilder {
} }
if (!unset.isEmpty()) { if (!unset.isEmpty()) {
logger.log(Level.WARNING, "protocols " + unset + " is not supported, only support: " + Arrays.toString(protocolArray)); logger.log(Level.WARNING, "protocols " + unset + " is not supported, only support: " + Arrays.toString(protocolArray));
} }
} }
if (!enabledCiphers.isEmpty()) { if (!enabledCiphers.isEmpty()) {
HashSet<String> set = new HashSet<>(); HashSet<String> set = new HashSet<>();

View File

@@ -288,7 +288,7 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
logger.info(threadName + this.getClass().getSimpleName() + ("TCP".equalsIgnoreCase(netprotocol) ? "" : ("." + netprotocol)) + " listen: " + (address.getHostString() + ":" + address.getPort()) logger.info(threadName + this.getClass().getSimpleName() + ("TCP".equalsIgnoreCase(netprotocol) ? "" : ("." + netprotocol)) + " listen: " + (address.getHostString() + ":" + address.getPort())
+ ", cpu: " + Utility.cpus() + ", responsePoolSize: " + responsePoolSize + ", bufferPoolSize: " + bufferPoolSize + ", cpu: " + Utility.cpus() + ", responsePoolSize: " + responsePoolSize + ", bufferPoolSize: " + bufferPoolSize
+ ", bufferCapacity: " + formatLenth(bufferCapacity) + ", maxbody: " + formatLenth(context.maxbody) + ", bufferCapacity: " + formatLenth(bufferCapacity) + ", maxbody: " + formatLenth(context.maxbody)
+ ", started in " + (System.currentTimeMillis() - context.getServerStartTime()) + " ms"); + ", started in " + (System.currentTimeMillis() - context.getServerStartTime()) + " ms\r\n");
} }
protected void postPrepareInit() { protected void postPrepareInit() {

View File

@@ -5,7 +5,7 @@
*/ */
package org.redkale.source; package org.redkale.source;
import org.redkale.util.AnyValue; import org.redkale.util.*;
/** /**
* *
@@ -17,9 +17,6 @@ import org.redkale.util.AnyValue;
* @author zhangjx * @author zhangjx
* @since 2.5.0 * @since 2.5.0
*/ */
public interface CacheSourceProvider { public interface CacheSourceProvider extends InstanceProvider<CacheSource> {
public boolean acceptsConf(AnyValue config);
public Class<? extends CacheSource> sourceClass();
} }

View File

@@ -5,7 +5,7 @@
*/ */
package org.redkale.source; package org.redkale.source;
import org.redkale.util.AnyValue; import org.redkale.util.*;
/** /**
* *
@@ -17,9 +17,6 @@ import org.redkale.util.AnyValue;
* @author zhangjx * @author zhangjx
* @since 2.5.0 * @since 2.5.0
*/ */
public interface DataSourceProvider { public interface DataSourceProvider extends InstanceProvider<DataSource> {
public boolean acceptsConf(AnyValue config);
public Class<? extends DataSource> sourceClass();
} }

View File

@@ -0,0 +1,34 @@
/*
*/
package org.redkale.util;
import java.util.*;
import javax.annotation.Priority;
/**
* 配置源Agent的Provider
*
*
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <V> XXXAgent
*
* @since 2.8.0
*/
public interface InstanceProvider<V> {
public boolean acceptsConf(AnyValue config);
public V createInstance();
//值大排前面
public static <P extends InstanceProvider> List<P> sort(List<P> providers) {
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
return providers;
}
}