This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new d20bd5e Implemented Pluginloader (#8429)
d20bd5e is described below
commit d20bd5e41244d346efa50379c4610c8eced9d5f3
Author: Daming <[email protected]>
AuthorDate: Tue Dec 1 11:33:34 2020 +0800
Implemented Pluginloader (#8429)
* feature: implemented plugin loader
* feature: implemented plugin loader
* improvement
* remove final keyword
---
.../agent/bootstrap/ShardingSphereAgent.java | 12 +-
.../agent/core/ShardingSphereTransformer.java | 6 +-
.../core/exception/AdviceNotFoundException.java | 25 +++
.../agent/core/plugin/PluginAdviceDefine.java | 113 ++++++-------
.../agent/core/plugin/PluginDefine.java | 80 +++++++++
.../agent/core/plugin/PluginLoader.java | 180 ++++++++++++++++++++-
.../shardingsphere/agent/core/plugin/Service.java | 40 +++++
7 files changed, 386 insertions(+), 70 deletions(-)
diff --git
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
b/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
index 360dfa3..76cce23 100644
---
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++
b/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
@@ -49,19 +49,23 @@ public class ShardingSphereAgent {
SingletonHolder.INSTANCE.put(agentConfiguration);
ByteBuddy byteBuddy = new ByteBuddy().with(TypeValidation.ENABLED);
-
+
AgentBuilder builder = new AgentBuilder.Default()
.with(byteBuddy)
.ignore(ElementMatchers.isSynthetic())
.or(ElementMatchers.nameStartsWith("org.apache.shardingsphere.agent."))
.or(ElementMatchers.not(ElementMatchers.nameStartsWith("org.apache.shardingsphere.")));
-
- PluginLoader pluginLoader = new PluginLoader();
-
+
+ PluginLoader pluginLoader = PluginLoader.getInstance();
+ pluginLoader.initialAllServices();
+
builder.type(pluginLoader.typeMatcher())
.transform(new ShardingSphereTransformer(pluginLoader))
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(new LoggingListener())
.installOn(instrumentation);
+
+ pluginLoader.startAllServices();
+ Runtime.getRuntime().addShutdownHook(new
Thread(pluginLoader::shutdownAllServices));
}
}
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
index 0e352c9..65de521 100644
---
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
@@ -62,7 +62,7 @@ public class ShardingSphereTransformer implements
AgentBuilder.Transformer {
final PluginAdviceDefine define =
pluginLoader.loadPluginAdviceDefine(typeDescription);
for (ConstructorPoint point : define.getConstructorPoints()) {
try {
- final ConstructorMethodInterceptor interceptor = new
ConstructorMethodInterceptor(pluginLoader.getInstance(point.getAdvice()));
+ final ConstructorMethodInterceptor interceptor = new
ConstructorMethodInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
newBuilder =
newBuilder.constructor(point.getConstructorMatcher())
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration().to(interceptor)));
// CHECKSTYLE:OFF
@@ -74,7 +74,7 @@ public class ShardingSphereTransformer implements
AgentBuilder.Transformer {
for (ClassStaticMethodPoint point :
define.getClassStaticMethodPoints()) {
try {
- final StaticMethodAroundInterceptor interceptor = new
StaticMethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+ final StaticMethodAroundInterceptor interceptor = new
StaticMethodAroundInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
newBuilder = newBuilder.method(point.getMethodsMatcher())
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
// CHECKSTYLE:OFF
@@ -86,7 +86,7 @@ public class ShardingSphereTransformer implements
AgentBuilder.Transformer {
for (InstanceMethodPoint point : define.getInstanceMethodPoints())
{
try {
- final MethodAroundInterceptor interceptor = new
MethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+ final MethodAroundInterceptor interceptor = new
MethodAroundInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
newBuilder = newBuilder.method(point.getMethodMatcher())
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
// CHECKSTYLE:OFF
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.java
new file mode 100644
index 0000000..1c59c54
--- /dev/null
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.apache.shardingsphere.agent.core.exception;
+
+/**
+ * Advice not found exception.
+ */
+public class AdviceNotFoundException extends RuntimeException {
+}
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
index fcc7b19..cbb74e2 100644
---
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
@@ -40,21 +40,33 @@ import java.util.List;
* </code>
*/
public final class PluginAdviceDefine {
-
+
+ private final String classNameOfTarget;
+
private final List<ConstructorPoint> constructorPoints;
-
+
private final List<InstanceMethodPoint> instanceMethodPoints;
-
+
private final List<ClassStaticMethodPoint> classStaticMethodPoints;
-
- private PluginAdviceDefine(final List<ConstructorPoint> constructorPoints,
+
+ private PluginAdviceDefine(final String classNameOfTarget,
+ final List<ConstructorPoint> constructorPoints,
final List<InstanceMethodPoint>
instanceMethodPoints,
final List<ClassStaticMethodPoint>
classStaticMethodPoints) {
+ this.classNameOfTarget = classNameOfTarget;
this.constructorPoints = constructorPoints;
this.instanceMethodPoints = instanceMethodPoints;
this.classStaticMethodPoints = classStaticMethodPoints;
}
-
+
+ /**
+ * Get class name of target.
+ * @return class name.
+ */
+ public String getClassNameOfTarget() {
+ return classNameOfTarget;
+ }
+
/**
* Intercept target class.
*
@@ -64,7 +76,7 @@ public final class PluginAdviceDefine {
public static Builder intercept(final String classNameOfTarget) {
return new Builder(classNameOfTarget);
}
-
+
/**
* To get static method point configurations.
*
@@ -73,7 +85,7 @@ public final class PluginAdviceDefine {
public List<ClassStaticMethodPoint> getClassStaticMethodPoints() {
return classStaticMethodPoints;
}
-
+
/**
* To get constructor point configurations.
*
@@ -82,7 +94,7 @@ public final class PluginAdviceDefine {
public List<ConstructorPoint> getConstructorPoints() {
return constructorPoints;
}
-
+
/**
* To get instance point configurations.
*
@@ -91,34 +103,23 @@ public final class PluginAdviceDefine {
public List<InstanceMethodPoint> getInstanceMethodPoints() {
return instanceMethodPoints;
}
-
+
/**
* Plugin advice configuration builder.
*/
public static final class Builder {
private final List<ConstructorPoint> constructorPoints =
Lists.newArrayList();
-
+
private final List<InstanceMethodPoint> instanceMethodPoints =
Lists.newArrayList();
-
+
private final List<ClassStaticMethodPoint> classStaticMethodPoints =
Lists.newArrayList();
-
+
private final String classNameOfTarget;
-
+
private Builder(final String classNameOfTarget) {
this.classNameOfTarget = classNameOfTarget;
}
-
- /**
- * Intercept the new target.
- *
- * @param classNameOfTarget the class name of target.
- * @return configuration builder.
- */
- public Builder intercept(final String classNameOfTarget) {
- // TODO not-implemented yet
- return this;
- }
-
+
/**
* Configure the intercepting point on constructor.
*
@@ -128,54 +129,54 @@ public final class PluginAdviceDefine {
public ConstructorPointBuilder onConstructor(final ElementMatcher<?
super MethodDescription> matcher) {
return new ConstructorPointBuilder(this, matcher);
}
-
+
/**
* Configure the intercepting point around instance method.
*
* @param matcher constraints
* @return configuration builder
*/
- public InstanceMethodPointBuilder method(final ElementMatcher<? super
MethodDescription> matcher) {
+ public InstanceMethodPointBuilder aroundInstanceMethod(final
ElementMatcher<? super MethodDescription> matcher) {
return new InstanceMethodPointBuilder(this, matcher);
}
-
+
/**
* Configure the intercepting point around instance method.
*
* @param matcher constraints
* @return configuration builder
*/
- public StaticMethodPointBuilder staticMethod(final ElementMatcher<?
super MethodDescription> matcher) {
+ public StaticMethodPointBuilder aroundClassStaticMethod(final
ElementMatcher<? super MethodDescription> matcher) {
return new StaticMethodPointBuilder(this, matcher);
}
-
-
+
+
/**
* Build configuration.
*
* @return plugin advice definition.
*/
public PluginAdviceDefine install() {
- return new PluginAdviceDefine(constructorPoints,
instanceMethodPoints, classStaticMethodPoints);
+ return new PluginAdviceDefine(classNameOfTarget,
constructorPoints, instanceMethodPoints, classStaticMethodPoints);
}
-
+
/**
* Instance method intercepting point configuration builder.
*/
public static final class InstanceMethodPointBuilder {
private final Builder builder;
-
+
private String classNameOfAdvice;
-
+
private boolean overrideArgs;
-
+
private ElementMatcher<? super MethodDescription> matcher;
-
+
private InstanceMethodPointBuilder(final Builder builder, final
ElementMatcher<? super MethodDescription> matcher) {
this.builder = builder;
this.matcher = matcher;
}
-
+
/**
* Configure implementation for interceptor point.
*
@@ -186,7 +187,7 @@ public final class PluginAdviceDefine {
this.classNameOfAdvice = classNameOfAdvice;
return this;
}
-
+
/**
* Configure whether or not override the origin method arguments.
*
@@ -197,7 +198,7 @@ public final class PluginAdviceDefine {
this.overrideArgs = overrideArgs;
return this;
}
-
+
/**
* Build instance methods configuration.
*
@@ -208,24 +209,24 @@ public final class PluginAdviceDefine {
return builder;
}
}
-
+
/**
* Static method intercepting point configuration builder.
*/
public static final class StaticMethodPointBuilder {
private final Builder builder;
-
+
private String classNameOfAdvice;
-
+
private boolean overrideArgs;
-
+
private ElementMatcher<? super MethodDescription> matcher;
-
+
private StaticMethodPointBuilder(final Builder builder, final
ElementMatcher<? super MethodDescription> matcher) {
this.builder = builder;
this.matcher = ElementMatchers.isStatic().and(matcher);
}
-
+
/**
* Configure implementation for intercepting point.
*
@@ -236,7 +237,7 @@ public final class PluginAdviceDefine {
this.classNameOfAdvice = classNameOfAdvice;
return this;
}
-
+
/**
* Configure whether or not override the origin method arguments.
*
@@ -247,7 +248,7 @@ public final class PluginAdviceDefine {
this.overrideArgs = overrideArgs;
return this;
}
-
+
/**
* Build static methods configuration.
*
@@ -257,24 +258,24 @@ public final class PluginAdviceDefine {
builder.classStaticMethodPoints.add(new
ClassStaticMethodPoint(matcher, classNameOfAdvice, overrideArgs));
return builder;
}
-
+
}
-
+
/**
* Instance constructor intercepting point configuration builder.
*/
public static final class ConstructorPointBuilder {
private final Builder builder;
-
+
private String classNameOfAdvice;
-
+
private ElementMatcher<? super MethodDescription> matcher;
-
+
private ConstructorPointBuilder(final Builder builder, final
ElementMatcher<? super MethodDescription> matcher) {
this.builder = builder;
this.matcher = ElementMatchers.isConstructor().and(matcher);
}
-
+
/**
* Configure implementation for intercepting point.
*
@@ -285,7 +286,7 @@ public final class PluginAdviceDefine {
this.classNameOfAdvice = classNameOfAdvice;
return this;
}
-
+
/**
* Build constructor point configuration.
*
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
new file mode 100644
index 0000000..5490542
--- /dev/null
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
@@ -0,0 +1,80 @@
+/*
+ * 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.apache.shardingsphere.agent.core.plugin;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Plugin definition.
+ */
+public abstract class PluginDefine {
+
+ private final Map<String, PluginAdviceDefine.Builder> defineMap =
Maps.newHashMap();
+
+ private final List<Class<? extends Service>> services =
Lists.newArrayList();
+
+ /**
+ * Configure the plugin here.
+ */
+ protected abstract void define();
+
+ protected PluginAdviceDefine.Builder intercept(final String
classNameOfTarget) {
+ if (defineMap.containsKey(classNameOfTarget)) {
+ return defineMap.get(classNameOfTarget);
+ }
+ PluginAdviceDefine.Builder builder =
PluginAdviceDefine.intercept(classNameOfTarget);
+ defineMap.put(classNameOfTarget, builder);
+ return builder;
+ }
+
+ /**
+ * Register service to agent.
+ *
+ * @param service the class of Service.
+ */
+ protected void registerService(final Class<? extends Service> service) {
+ services.add(service);
+ }
+
+ /**
+ * To build Plugin definition.
+ *
+ * @return configurations.
+ */
+ public final List<PluginAdviceDefine> build() {
+ define();
+ return defineMap.values().stream()
+ .map(PluginAdviceDefine.Builder::install)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * To get all services.
+ *
+ * @return all services.
+ */
+ public List<Class<? extends Service>> getAllServics() {
+ return services;
+ }
+}
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
index 7a7f548..d35cff8 100644
---
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
@@ -18,31 +18,149 @@
package org.apache.shardingsphere.agent.core.plugin;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteStreams;
import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
+import net.bytebuddy.matcher.ElementMatchers;
+import org.apache.shardingsphere.agent.core.common.AgentPathLocator;
+import org.apache.shardingsphere.agent.core.exception.AdviceNotFoundException;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
/**
* Plugins loader.
- * TODO not-implemented yet
*/
-public class PluginLoader extends ClassLoader {
+@Slf4j
+public final class PluginLoader extends ClassLoader implements Closeable {
+
+ private static final PluginLoader INSTANCE = new PluginLoader();
private final ConcurrentHashMap<String, Object> objectPool = new
ConcurrentHashMap<>();
private final ReentrantLock lock = new ReentrantLock();
+ private final List<JarFile> jars = Lists.newArrayList();
+
+ private final List<Service> services = Lists.newArrayList();
+
+ private Map<String, PluginAdviceDefine> pluginDefineMap;
+
+ private PluginLoader() {
+ try {
+ pluginDefineMap = loadAllPlugins();
+ } catch (IOException ioe) {
+ log.error("Failed to load plugins.");
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(final String name) throws
ClassNotFoundException {
+ String path = classNameToPath(name);
+ for (JarFile jar : jars) {
+ ZipEntry entry = jar.getEntry(path);
+ if (Objects.nonNull(entry)) {
+ try {
+ byte[] data =
ByteStreams.toByteArray(jar.getInputStream(entry));
+ return defineClass(name, data, 0, data.length);
+ } catch (IOException ioe) {
+ log.error("Failed to load class {}.", name, ioe);
+ }
+ }
+ }
+ throw new ClassNotFoundException("Class " + name + " not found.");
+ }
+
+ @Override
+ public void close() {
+ for (JarFile jar : jars) {
+ try {
+ jar.close();
+ } catch (IOException ioe) {
+ log.error("", ioe);
+ }
+ }
+ }
+
+ /**
+ * To get plugin loader instance.
+ *
+ * @return plugin loader
+ */
+ public static PluginLoader getInstance() {
+ return INSTANCE;
+ }
+
+ private Map<String, PluginAdviceDefine> loadAllPlugins() throws
IOException {
+ File[] jarFiles = AgentPathLocator.getAgentPath().listFiles(file ->
file.getName().endsWith(".jar"));
+ ImmutableMap.Builder<String, PluginAdviceDefine> pluginDefineMap =
ImmutableMap.builder();
+ if (jarFiles == null) {
+ return pluginDefineMap.build();
+ }
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ for (File jarFile : jarFiles) {
+ outputStream.reset();
+
+ JarFile jar = new JarFile(jarFile, true);
+ jars.add(jar);
+
+ Attributes attributes = jar.getManifest().getMainAttributes();
+ String entrypoint = attributes.getValue("Entrypoint");
+ if (Strings.isNullOrEmpty(entrypoint)) {
+ log.warn("Entrypoint is not setting in {}.",
jarFile.getName());
+ continue;
+ }
+
+
ByteStreams.copy(jar.getInputStream(jar.getEntry(classNameToPath(entrypoint))),
outputStream);
+
+ try {
+ PluginDefine config = (PluginDefine) defineClass(entrypoint,
outputStream.toByteArray(), 0, outputStream.size())
+ .newInstance();
+
+ config.getAllServics().forEach(klass -> {
+ try {
+ services.add(klass.newInstance());
+ } catch (InstantiationException | IllegalAccessException
e) {
+ log.error("Failed to create service instance, {}.",
klass.getTypeName(), e);
+ }
+ });
+
+ config.build().forEach(plugin ->
pluginDefineMap.put(plugin.getClassNameOfTarget(), plugin));
+ } catch (InstantiationException | IllegalAccessException e) {
+ log.error("Failed to load plugin definition, {}.", entrypoint,
e);
+ }
+ }
+ return pluginDefineMap.build();
+ }
+
+ private String classNameToPath(final String className) {
+ return className.replace(".", "/") + ".class";
+ }
+
/**
* To find all intercepting target classes then to build TypeMatcher.
*
* @return type matcher
*/
public ElementMatcher<? super TypeDescription> typeMatcher() {
- return null;
+ return
ElementMatchers.anyOf(pluginDefineMap.keySet().stream().map(ElementMatchers::named).toArray());
}
/**
@@ -52,7 +170,7 @@ public class PluginLoader extends ClassLoader {
* @return contains when it is true.
*/
public boolean containsType(final TypeDescription typeDescription) {
- return false;
+ return pluginDefineMap.containsKey(typeDescription.getTypeName());
}
/**
@@ -62,18 +180,21 @@ public class PluginLoader extends ClassLoader {
* @return the plugin definition configurations.
*/
public PluginAdviceDefine loadPluginAdviceDefine(final TypeDescription
typeDescription) {
- return null;
+ if (pluginDefineMap.containsKey(typeDescription.getTypeName())) {
+ return pluginDefineMap.get(typeDescription.getTypeName());
+ }
+ throw new AdviceNotFoundException();
}
/**
* To get or create instance of the advice class. Create new one and
caching when it is not exist.
*
* @param classNameOfAdvice the class name of advice
- * @param <T> the advice type.
+ * @param <T> the advice type.
* @return instance of advice
*/
@SneakyThrows({ClassNotFoundException.class, IllegalAccessException.class,
InstantiationException.class})
- public <T> T getInstance(final String classNameOfAdvice) {
+ public <T> T getOrCreateInstance(final String classNameOfAdvice) {
if (objectPool.containsKey(classNameOfAdvice)) {
return (T) objectPool.get(classNameOfAdvice);
@@ -92,4 +213,49 @@ public class PluginLoader extends ClassLoader {
lock.unlock();
}
}
+
+ /**
+ * Initial all services.
+ */
+ public void initialAllServices() {
+ services.forEach(service -> {
+ try {
+ service.setup();
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ log.error("Failed to initial service.");
+ }
+ });
+ }
+
+ /**
+ * Start all services.
+ */
+ public void startAllServices() {
+ services.forEach(service -> {
+ try {
+ service.start();
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ log.error("Failed to start service.");
+ }
+ });
+ }
+
+ /**
+ * Shutdown all services.
+ */
+ public void shutdownAllServices() {
+ services.forEach(service -> {
+ try {
+ service.cleanup();
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ log.error("Failed to shutdown service.");
+ }
+ });
+ }
}
diff --git
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
new file mode 100644
index 0000000..da30bd1
--- /dev/null
+++
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
@@ -0,0 +1,40 @@
+/*
+ * 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.apache.shardingsphere.agent.core.plugin;
+
+/**
+ * Service that the lifecycle is from the agent startup to shutdown.
+ */
+public interface Service {
+
+ /**
+ * Setup the service, like to configure or to initial.
+ */
+ void setup();
+
+ /**
+ * Start up the service.
+ */
+ void start();
+
+ /**
+ * Cleanup the service.
+ */
+ void cleanup();
+}