Skip to content

Commit

Permalink
Merge pull request #302 from dromara/dev
Browse files Browse the repository at this point in the history
Unified ServiceLoader Optimize
  • Loading branch information
yanhom1314 committed Jul 6, 2023
2 parents 9311be5 + ebb6aff commit 93afcd5
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.dromara.dynamictp.common.util;

import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;

/**
* Unified ServiceLoader Helper
*
* @author xs.Tao
* @since 1.1.4
*/
public class ExtensionServiceLoader {

private static final Map<Class<?>, List<?>> EXTENSION_MAP = new ConcurrentHashMap<>();

private ExtensionServiceLoader() {
}

/**
* load service
* @param clazz SPI interface
* @return services
* @param <T> interface class
*/
@SuppressWarnings("unchecked")
public static <T> List<T> get(Class<T> clazz) {
List<T> services = (List<T>) EXTENSION_MAP.get(clazz);
if (CollectionUtils.isEmpty(services)) {
services = load(clazz);
if (CollectionUtils.isNotEmpty(services)) {
EXTENSION_MAP.put(clazz, services);
}
}
return services;
}

/**
* load the first service
* @param clazz SPI interface
* @return service
* @param <T> interface class
*/
public static <T> T getFirst(Class<T> clazz) {
List<T> services = get(clazz);
return CollectionUtils.isEmpty(services) ? null : services.get(0);
}

private static <T> List<T> load(Class<T> clazz) {
ServiceLoader<T> serviceLoader = ServiceLoader.load(clazz);
List<T> services = new ArrayList<>();
for (T service : serviceLoader) {
services.add(service);
}
return services;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@

package org.dromara.dynamictp.core.handler;

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.entity.ThreadPoolStats;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;
import org.dromara.dynamictp.core.monitor.collector.InternalLogCollector;
import org.dromara.dynamictp.core.monitor.collector.LogCollector;
import org.dromara.dynamictp.core.monitor.collector.MetricsCollector;
import org.dromara.dynamictp.core.monitor.collector.MicroMeterCollector;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
* CollectorHandler related
Expand All @@ -42,10 +42,8 @@ public final class CollectorHandler {
private static final Map<String, MetricsCollector> COLLECTORS = Maps.newHashMap();

private CollectorHandler() {
ServiceLoader<MetricsCollector> loader = ServiceLoader.load(MetricsCollector.class);
for (MetricsCollector collector : loader) {
COLLECTORS.put(collector.type(), collector);
}
List<MetricsCollector> loadedCollectors = ExtensionServiceLoader.get(MetricsCollector.class);
loadedCollectors.forEach(collector -> COLLECTORS.put(collector.type(), collector));

MetricsCollector microMeterCollector = new MicroMeterCollector();
LogCollector logCollector = new LogCollector();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@

package org.dromara.dynamictp.core.handler;

import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.dynamictp.common.em.ConfigFileTypeEnum;
import org.dromara.dynamictp.common.parser.config.ConfigParser;
import org.dromara.dynamictp.common.parser.config.JsonConfigParser;
import org.dromara.dynamictp.common.parser.config.PropertiesConfigParser;
import org.dromara.dynamictp.common.parser.config.YamlConfigParser;
import com.google.common.collect.Lists;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
* ConfigHandler related
Expand All @@ -41,11 +42,10 @@ public final class ConfigHandler {
private static final List<ConfigParser> PARSERS = Lists.newArrayList();

private ConfigHandler() {
ServiceLoader<ConfigParser> loader = ServiceLoader.load(ConfigParser.class);
for (ConfigParser configParser : loader) {
PARSERS.add(configParser);
List<ConfigParser> loadedParses = ExtensionServiceLoader.get(ConfigParser.class);
if (CollectionUtils.isNotEmpty(loadedParses)) {
PARSERS.addAll(loadedParses);
}

PARSERS.add(new PropertiesConfigParser());
PARSERS.add(new YamlConfigParser());
PARSERS.add(new JsonConfigParser());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@

package org.dromara.dynamictp.core.handler;

import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.em.NotifyItemEnum;
import org.dromara.dynamictp.common.entity.NotifyItem;
import org.dromara.dynamictp.common.entity.TpMainFields;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;
import org.dromara.dynamictp.core.notifier.DtpDingNotifier;
import org.dromara.dynamictp.core.notifier.DtpLarkNotifier;
import org.dromara.dynamictp.core.notifier.DtpNotifier;
import org.dromara.dynamictp.core.notifier.DtpWechatNotifier;
import org.dromara.dynamictp.core.notifier.manager.NotifyHelper;
import org.dromara.dynamictp.core.notifier.base.DingNotifier;
import org.dromara.dynamictp.core.notifier.base.LarkNotifier;
import org.dromara.dynamictp.core.notifier.base.WechatNotifier;
import org.dromara.dynamictp.core.notifier.context.DtpNotifyCtxHolder;
import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.core.notifier.manager.NotifyHelper;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
* NotifierHandler related
Expand All @@ -48,10 +48,9 @@ public final class NotifierHandler {
private static final Map<String, DtpNotifier> NOTIFIERS = new HashMap<>();

private NotifierHandler() {
ServiceLoader<DtpNotifier> loader = ServiceLoader.load(DtpNotifier.class);
for (DtpNotifier notifier : loader) {
NOTIFIERS.put(notifier.platform(), notifier);
}
List<DtpNotifier> loadedNotifiers = ExtensionServiceLoader.get(DtpNotifier.class);
loadedNotifiers.forEach(notifier -> NOTIFIERS.put(notifier.platform(), notifier));

DtpNotifier dingNotifier = new DtpDingNotifier(new DingNotifier());
DtpNotifier wechatNotifier = new DtpWechatNotifier(new WechatNotifier());
DtpNotifier larkNotifier = new DtpLarkNotifier(new LarkNotifier());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
package org.dromara.dynamictp.core.plugin;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;

/**
* DtpInterceptorRegistry related
Expand All @@ -39,12 +40,14 @@ public class DtpInterceptorRegistry {
private static final List<DtpInterceptor> INTERCEPTORS = new ArrayList<>();

static {
ServiceLoader<DtpInterceptor> loader = ServiceLoader.load(DtpInterceptor.class);
for (DtpInterceptor interceptor : loader) {
INTERCEPTORS.add(interceptor);
List<DtpInterceptor> loadedInterceptors = ExtensionServiceLoader.get(DtpInterceptor.class);
if (CollectionUtils.isNotEmpty(loadedInterceptors)) {
INTERCEPTORS.addAll(loadedInterceptors);
}
}

private DtpInterceptorRegistry() { }

public static void register(DtpInterceptor dtpInterceptor) {
log.info("DynamicTp register DtpInterceptor: {}", dtpInterceptor);
INTERCEPTORS.add(dtpInterceptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@

import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.ex.DtpException;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;

import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

Expand Down Expand Up @@ -52,9 +53,8 @@ public static RejectedExecutionHandler buildRejectedHandler(String name) {
} else if (Objects.equals(name, DISCARD_POLICY.getName())) {
return new ThreadPoolExecutor.DiscardPolicy();
}

ServiceLoader<RejectedExecutionHandler> serviceLoader = ServiceLoader.load(RejectedExecutionHandler.class);
for (RejectedExecutionHandler handler : serviceLoader) {
List<RejectedExecutionHandler> loadedHandlers = ExtensionServiceLoader.get(RejectedExecutionHandler.class);
for (RejectedExecutionHandler handler : loadedHandlers) {
String handlerName = handler.getClass().getSimpleName();
if (name.equalsIgnoreCase(handlerName)) {
return handler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@
import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.pattern.singleton.Singleton;
import org.dromara.dynamictp.common.properties.DtpProperties;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;
import org.dromara.dynamictp.core.spring.PropertiesBinder;
import org.springframework.core.env.Environment;

import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;

/**
* BinderHelper related
Expand All @@ -36,20 +35,21 @@
*/
@Slf4j
public class BinderHelper {


private BinderHelper() { }

private static PropertiesBinder getBinder() {
PropertiesBinder binder = Singleton.INST.get(PropertiesBinder.class);
if (Objects.nonNull(binder)) {
return binder;
}
final Iterator<PropertiesBinder> iterator = ServiceLoader.load(PropertiesBinder.class).iterator();
if (!iterator.hasNext()) {
final PropertiesBinder loadedFirstBinder = ExtensionServiceLoader.getFirst(PropertiesBinder.class);
if (Objects.isNull(loadedFirstBinder)) {
log.error("DynamicTp refresh, no SPI for org.dromara.dynamictp.core.spring.PropertiesBinder.");
return null;
}
binder = iterator.next();
Singleton.INST.single(PropertiesBinder.class, binder);
return binder;
Singleton.INST.single(PropertiesBinder.class, loadedFirstBinder);
return loadedFirstBinder;
}

public static void bindDtpProperties(Map<?, Object> properties, DtpProperties dtpProperties) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@

package org.dromara.dynamictp.core.support.task.wrapper;

import org.dromara.dynamictp.common.util.StringUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.dynamictp.common.util.ExtensionServiceLoader;
import org.dromara.dynamictp.common.util.StringUtil;

import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;

import static java.util.stream.Collectors.toList;
Expand All @@ -39,9 +39,9 @@ public class TaskWrappers {
private static final List<TaskWrapper> TASK_WRAPPERS = Lists.newArrayList();

private TaskWrappers() {
ServiceLoader<TaskWrapper> loader = ServiceLoader.load(TaskWrapper.class);
for (TaskWrapper taskWrapper : loader) {
TASK_WRAPPERS.add(taskWrapper);
List<TaskWrapper> loadedWrappers = ExtensionServiceLoader.get(TaskWrapper.class);
if (CollectionUtils.isNotEmpty(loadedWrappers)) {
TASK_WRAPPERS.addAll(loadedWrappers);
}

TASK_WRAPPERS.add(new TtlTaskWrapper());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.dromara.dynamictp.core.support.DynamicTp;
import org.dromara.dynamictp.core.support.ThreadPoolBuilder;
import org.dromara.dynamictp.core.support.ThreadPoolCreator;
import org.dromara.dynamictp.core.support.task.wrapper.TtlTaskWrapper;
import org.dromara.dynamictp.core.thread.DtpExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -91,6 +92,7 @@ public ThreadPoolExecutor dtpExecutor2() {
.workQueue(SYNCHRONOUS_QUEUE.getName(), null, false, null)
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationSeconds(5)
.taskWrapper(new TtlTaskWrapper())
.buildDynamic();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.dromara.dynamictp.test.common.util;

import org.dromara.dynamictp.common.util.ExtensionServiceLoader;
import org.dromara.dynamictp.core.plugin.DtpInterceptor;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;

import java.util.List;

/**
* ExtensionServiceLoader test case
*/
public class ExtensionServiceLoaderTest {

@Test
public void test(){
List<DtpInterceptor> loadedInterceptors = ExtensionServiceLoader.get(DtpInterceptor.class);
Assertions.assertTrue(loadedInterceptors.stream().anyMatch(it-> it instanceof TestInterceptorLoader));
}

}
Loading

0 comments on commit 93afcd5

Please sign in to comment.