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 0bfe11e  feature: introduce shardingsphere agent (#8307)
0bfe11e is described below

commit 0bfe11eb839d1bb2bda84ae1cf7495eb6c0c8bda
Author: Daming <[email protected]>
AuthorDate: Mon Nov 23 22:54:11 2020 +0800

    feature: introduce shardingsphere agent (#8307)
    
    * feature: introduce shardingsphere agent
    
    * replace version with property
    
    * fix checkstyle
    
    * fix javadoc
    
    * fix checkstyle
    
    * fix javadoc
    
    * fix javadoc
---
 .../shardingsphere-agent-bootstrap/pom.xml         |  26 ++
 .../agent/bootstrap/ShardingSphereAgent.java       |  28 +-
 .../shardingsphere-agent-core/pom.xml              |  74 +++++
 .../shardingsphere/agent/core/LoggingListener.java |  58 ++++
 .../agent/core/ShardingSphereTransformer.java      | 103 +++++++
 .../agent/core/plugin/PluginAdviceDefine.java      | 300 +++++++++++++++++++++
 .../agent/core/plugin/PluginLoader.java            |  95 +++++++
 .../core/plugin/advice/ConstructorAdvice.java}     |  26 +-
 .../advice/ConstructorMethodInterceptor.java       |  54 ++++
 .../core/plugin/advice/MethodAroundAdvice.java     |  57 ++++
 .../plugin/advice/MethodAroundInterceptor.java     |  96 +++++++
 .../plugin/advice/MethodInvocationResult.java}     |  48 ++--
 .../core/plugin/advice/OverrideArgsInvoker.java}   |  27 +-
 .../plugin/advice/StaticMethodAroundAdvice.java    |  57 ++++
 .../advice/StaticMethodAroundInterceptor.java      |  94 +++++++
 .../agent/core/plugin/advice/TargetObject.java}    |  33 ++-
 .../core/plugin/point/ClassStaticMethodPoint.java  |  68 +++++
 .../agent/core/plugin/point/ConstructorPoint.java  |  55 ++++
 .../core/plugin/point/InstanceMethodPoint.java     |  66 +++++
 19 files changed, 1292 insertions(+), 73 deletions(-)

diff --git a/shardingsphere-agent/shardingsphere-agent-bootstrap/pom.xml 
b/shardingsphere-agent/shardingsphere-agent-bootstrap/pom.xml
index 53fff43..f263a85 100644
--- a/shardingsphere-agent/shardingsphere-agent-bootstrap/pom.xml
+++ b/shardingsphere-agent/shardingsphere-agent-bootstrap/pom.xml
@@ -29,6 +29,7 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <shade.package>org.apache.shardingsphere.dependencies</shade.package>
         
<premain.class>org.apache.shardingsphere.agent.bootstrap.ShardingSphereAgent</premain.class>
         <can.redefine.classes>true</can.redefine.classes>
         <can.retransform.classes>true</can.retransform.classes>
@@ -40,6 +41,19 @@
             <artifactId>shardingsphere-agent-core</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>net.bytebuddy</groupId>
+            <artifactId>byte-buddy</artifactId>
+            <version>${bytebuddy.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.bytebuddy</groupId>
+            <artifactId>byte-buddy-agent</artifactId>
+            <version>${bytebuddy.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -72,9 +86,21 @@
                             </transformers>
                             <artifactSet>
                                 <excludes>
+                                    
<exclude>net.bytebuddy:byte-buddy:jar:</exclude>
+                                    <exclude>com.google.*:*</exclude>
+                                    <exclude>com.google.guava:guava</exclude>
+                                    
<exclude>org.checkerframework:checker-compat-qual</exclude>
+                                    
<exclude>org.codehaus.mojo:animal-sniffer-annotations</exclude>
+                                    <exclude>io.perfmark:*</exclude>
                                     <exclude>org.slf4j:*</exclude>
                                 </excludes>
                             </artifactSet>
+                            <relocations>
+                                <relocation>
+                                    <pattern>net.bytebuddy</pattern>
+                                    
<shadedPattern>${shade.package}.net.bytebuddy</shadedPattern>
+                                </relocation>
+                            </relocations>
                         </configuration>
                     </execution>
                 </executions>
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 817fe08..360dfa3 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
@@ -18,12 +18,20 @@
 
 package org.apache.shardingsphere.agent.bootstrap;
 
-import java.io.IOException;
-import java.lang.instrument.Instrumentation;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.agent.builder.AgentBuilder;
+import net.bytebuddy.dynamic.scaffold.TypeValidation;
+import net.bytebuddy.matcher.ElementMatchers;
+import org.apache.shardingsphere.agent.core.LoggingListener;
+import org.apache.shardingsphere.agent.core.ShardingSphereTransformer;
 import org.apache.shardingsphere.agent.core.config.AgentConfiguration;
 import org.apache.shardingsphere.agent.core.config.AgentConfigurationLoader;
+import org.apache.shardingsphere.agent.core.plugin.PluginLoader;
 import org.apache.shardingsphere.agent.core.utils.SingletonHolder;
 
+import java.io.IOException;
+import java.lang.instrument.Instrumentation;
+
 /**
  * ShardingSphere agent.
  */
@@ -39,5 +47,21 @@ public class ShardingSphereAgent {
     public static void premain(final String agentArgs, final Instrumentation 
instrumentation) throws IOException {
         AgentConfiguration agentConfiguration = 
AgentConfigurationLoader.load();
         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();
+
+        builder.type(pluginLoader.typeMatcher())
+               .transform(new ShardingSphereTransformer(pluginLoader))
+               .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
+               .with(new LoggingListener())
+               .installOn(instrumentation);
     }
 }
diff --git a/shardingsphere-agent/shardingsphere-agent-core/pom.xml 
b/shardingsphere-agent/shardingsphere-agent-core/pom.xml
index f0c7b4a..9e57825 100644
--- a/shardingsphere-agent/shardingsphere-agent-core/pom.xml
+++ b/shardingsphere-agent/shardingsphere-agent-core/pom.xml
@@ -27,12 +27,86 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>shardingsphere-agent-core</artifactId>
+    
+    <properties>
+        <shade.package>org.apache.shardingsphere.dependencies</shade.package>
+    </properties>
 
     <dependencies>
         <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>net.bytebuddy</groupId>
+            <artifactId>byte-buddy</artifactId>
+            <version>${bytebuddy.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.bytebuddy</groupId>
+            <artifactId>byte-buddy-agent</artifactId>
+            <version>${bytebuddy.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+
     </dependencies>
 
+    <build>
+        <finalName>shardingsphere-agent</finalName>
+        <plugins>
+            <plugin>
+                <artifactId>maven-shade-plugin</artifactId>
+                <configuration>
+                    
<createDependencyReducedPom>false</createDependencyReducedPom>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <artifactSet>
+                                <excludes>
+                                    
<exclude>net.bytebuddy:byte-buddy:jar:</exclude>
+                                    <exclude>com.google.*:*</exclude>
+                                    <exclude>com.google.guava:guava</exclude>
+                                    
<exclude>org.checkerframework:checker-compat-qual</exclude>
+                                    
<exclude>org.codehaus.mojo:animal-sniffer-annotations</exclude>
+                                    <exclude>io.perfmark:*</exclude>
+                                    <exclude>org.slf4j:*</exclude>
+                                </excludes>
+                            </artifactSet>
+                            <relocations>
+                                <relocation>
+                                    <pattern>com.google</pattern>
+                                    
<shadedPattern>${shade.package}.com.google</shadedPattern>
+                                </relocation>
+                                <relocation>
+                                    <pattern>io.perfmark</pattern>
+                                    
<shadedPattern>${shade.package}.io.perfmark</shadedPattern>
+                                </relocation>
+                                <relocation>
+                                    <pattern>org.slf4j</pattern>
+                                    
<shadedPattern>${shade.package}.org.slf4j</shadedPattern>
+                                </relocation>
+                                <relocation>
+                                    <pattern>org.checkerframework</pattern>
+                                    
<shadedPattern>${shade.package}.org.checkerframework</shadedPattern>
+                                </relocation>
+                            </relocations>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/LoggingListener.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/LoggingListener.java
new file mode 100644
index 0000000..34d0934
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/LoggingListener.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.agent.builder.AgentBuilder;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.DynamicType;
+import net.bytebuddy.utility.JavaModule;
+
+/**
+ * Listener to log what is informed about events that occur during an 
instrumentation process.
+ */
+@Slf4j
+public class LoggingListener implements AgentBuilder.Listener {
+
+    @Override
+    public void onDiscovery(final String typeName, final ClassLoader 
classLoader, final JavaModule module, final boolean loaded) {
+
+    }
+
+    @Override
+    public void onTransformation(final TypeDescription typeDescription, final 
ClassLoader classLoader, final JavaModule module, final boolean loaded, final 
DynamicType dynamicType) {
+        if (log.isDebugEnabled()) {
+            log.debug("On transformation class {}.", 
typeDescription.getTypeName());
+        }
+    }
+
+    @Override
+    public void onIgnored(final TypeDescription typeDescription, final 
ClassLoader classLoader, final JavaModule module, final boolean loaded) {
+    }
+
+    @Override
+    public void onError(final String typeName, final ClassLoader classLoader, 
final JavaModule module, final boolean loaded, final Throwable throwable) {
+        log.error("Failed to instrument {}.", typeName, throwable);
+    }
+
+    @Override
+    public void onComplete(final String typeName, final ClassLoader 
classLoader, final JavaModule module, final boolean loaded) {
+
+    }
+}
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
new file mode 100644
index 0000000..0e352c9
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.agent.builder.AgentBuilder;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.DynamicType;
+import net.bytebuddy.implementation.FieldAccessor;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.implementation.SuperMethodCall;
+import net.bytebuddy.jar.asm.Opcodes;
+import net.bytebuddy.utility.JavaModule;
+import org.apache.shardingsphere.agent.core.plugin.PluginAdviceDefine;
+import org.apache.shardingsphere.agent.core.plugin.PluginLoader;
+import 
org.apache.shardingsphere.agent.core.plugin.advice.ConstructorMethodInterceptor;
+import 
org.apache.shardingsphere.agent.core.plugin.advice.MethodAroundInterceptor;
+import 
org.apache.shardingsphere.agent.core.plugin.advice.StaticMethodAroundInterceptor;
+import org.apache.shardingsphere.agent.core.plugin.advice.TargetObject;
+import 
org.apache.shardingsphere.agent.core.plugin.point.ClassStaticMethodPoint;
+import org.apache.shardingsphere.agent.core.plugin.point.ConstructorPoint;
+import org.apache.shardingsphere.agent.core.plugin.point.InstanceMethodPoint;
+
+import java.util.Map;
+
+/**
+ *  Shardingsphere transformer.
+ */
+@Slf4j
+public class ShardingSphereTransformer implements AgentBuilder.Transformer {
+
+    private final PluginLoader pluginLoader;
+
+    public ShardingSphereTransformer(final PluginLoader pluginLoader) {
+        this.pluginLoader = pluginLoader;
+    }
+
+    @Override
+    public DynamicType.Builder<?> transform(final DynamicType.Builder<?> 
builder, final TypeDescription typeDescription, final ClassLoader classLoader, 
final JavaModule module) {
+        if (pluginLoader.containsType(typeDescription)) {
+
+            DynamicType.Builder<?> newBuilder = 
builder.defineField("_SSExtraData_", Map.class, Opcodes.ACC_PRIVATE | 
Opcodes.ACC_VOLATILE)
+                    .implement(TargetObject.class)
+                    .intercept(FieldAccessor.ofField("_SSExtraData_"));
+
+            final PluginAdviceDefine define = 
pluginLoader.loadPluginAdviceDefine(typeDescription);
+            for (ConstructorPoint point : define.getConstructorPoints()) {
+                try {
+                    final ConstructorMethodInterceptor interceptor = new 
ConstructorMethodInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    newBuilder = 
newBuilder.constructor(point.getConstructorMatcher())
+                            
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration().to(interceptor)));
+                    // CHECKSTYLE:OFF
+                } catch (Exception e) {
+                    // CHECKSTYLE:ON
+                    log.error("Failed to load advice class: {}", 
point.getAdvice(), e);
+                }
+            }
+
+            for (ClassStaticMethodPoint point : 
define.getClassStaticMethodPoints()) {
+                try {
+                    final StaticMethodAroundInterceptor interceptor = new 
StaticMethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    newBuilder = newBuilder.method(point.getMethodsMatcher())
+                            
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
+                    // CHECKSTYLE:OFF
+                } catch (Exception e) {
+                    // CHECKSTYLE:ON
+                    log.error("Failed to load advice class: {}", 
point.getAdvice(), e);
+                }
+            }
+
+            for (InstanceMethodPoint point : define.getInstanceMethodPoints()) 
{
+                try {
+                    final MethodAroundInterceptor interceptor = new 
MethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    newBuilder = newBuilder.method(point.getMethodMatcher())
+                            
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
+                    // CHECKSTYLE:OFF
+                } catch (Exception e) {
+                    // CHECKSTYLE:ON
+                    log.error("Failed to load advice class: {}", 
point.getAdvice(), e);
+                }
+            }
+            return newBuilder;
+        }
+
+        return builder;
+    }
+}
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
new file mode 100644
index 0000000..fcc7b19
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
@@ -0,0 +1,300 @@
+/*
+ * 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 net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import net.bytebuddy.matcher.ElementMatchers;
+import 
org.apache.shardingsphere.agent.core.plugin.point.ClassStaticMethodPoint;
+import org.apache.shardingsphere.agent.core.plugin.point.ConstructorPoint;
+import org.apache.shardingsphere.agent.core.plugin.point.InstanceMethodPoint;
+
+import java.util.List;
+
+/**
+ * Plugin advice define.
+ *
+ * <code>
+ * PluginAdviceDefine.intercept("Target.class")
+ * .onConstructor(ElementMatchers.any()).implement("Advice.class").build()
+ * .method(ElementMatchers.named("greet").implement("Advice.class").build()
+ * 
.staticMethod(ElementMatchers.named("of").implement("OfAdvice.class").build()
+ * .install();
+ * </code>
+ */
+public final class PluginAdviceDefine {
+
+    private final List<ConstructorPoint> constructorPoints;
+
+    private final List<InstanceMethodPoint> instanceMethodPoints;
+
+    private final List<ClassStaticMethodPoint> classStaticMethodPoints;
+
+    private PluginAdviceDefine(final List<ConstructorPoint> constructorPoints,
+                               final List<InstanceMethodPoint> 
instanceMethodPoints,
+                               final List<ClassStaticMethodPoint> 
classStaticMethodPoints) {
+        this.constructorPoints = constructorPoints;
+        this.instanceMethodPoints = instanceMethodPoints;
+        this.classStaticMethodPoints = classStaticMethodPoints;
+    }
+
+    /**
+     * Intercept target class.
+     *
+     * @param classNameOfTarget a class name of wanted advice target.
+     * @return builder.
+     */
+    public static Builder intercept(final String classNameOfTarget) {
+        return new Builder(classNameOfTarget);
+    }
+
+    /**
+     * To get static method point configurations.
+     *
+     * @return series of static method point configuration.
+     */
+    public List<ClassStaticMethodPoint> getClassStaticMethodPoints() {
+        return classStaticMethodPoints;
+    }
+
+    /**
+     * To get constructor point configurations.
+     *
+     * @return series of constructor point configuration.
+     */
+    public List<ConstructorPoint> getConstructorPoints() {
+        return constructorPoints;
+    }
+
+    /**
+     * To get instance point configurations.
+     *
+     * @return series of instance method point configuration.
+     */
+    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.
+         *
+         * @param matcher constraints
+         * @return configuration builder
+         */
+        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) {
+            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) {
+            return new StaticMethodPointBuilder(this, matcher);
+        }
+
+
+        /**
+         * Build configuration.
+         *
+         * @return plugin advice definition.
+         */
+        public PluginAdviceDefine install() {
+            return new PluginAdviceDefine(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.
+             *
+             * @param classNameOfAdvice the class name of advice
+             * @return instance method point builder.
+             */
+            public InstanceMethodPointBuilder implement(final String 
classNameOfAdvice) {
+                this.classNameOfAdvice = classNameOfAdvice;
+                return this;
+            }
+
+            /**
+             * Configure whether or not override the origin method arguments.
+             *
+             * @param overrideArgs whether to override origin method arguments.
+             * @return instance method point configurer.
+             */
+            public InstanceMethodPointBuilder overrideArgs(final boolean 
overrideArgs) {
+                this.overrideArgs = overrideArgs;
+                return this;
+            }
+
+            /**
+             * Build instance methods configuration.
+             *
+             * @return plugin advice builder.
+             */
+            public Builder build() {
+                builder.instanceMethodPoints.add(new 
InstanceMethodPoint(matcher, classNameOfAdvice, overrideArgs));
+                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.
+             *
+             * @param classNameOfAdvice the class name of advice
+             * @return static method point configurer.
+             */
+            public StaticMethodPointBuilder implement(final String 
classNameOfAdvice) {
+                this.classNameOfAdvice = classNameOfAdvice;
+                return this;
+            }
+
+            /**
+             * Configure whether or not override the origin method arguments.
+             *
+             * @param overrideArgs whether to override origin method arguments.
+             * @return static method point configurer.
+             */
+            public StaticMethodPointBuilder overrideArgs(final boolean 
overrideArgs) {
+                this.overrideArgs = overrideArgs;
+                return this;
+            }
+
+            /**
+             * Build static methods configuration.
+             *
+             * @return plugin advice builder.
+             */
+            public Builder build() {
+                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.
+             *
+             * @param classNameOfAdvice the class name of advice
+             * @return constructor point builder.
+             */
+            public ConstructorPointBuilder implement(final String 
classNameOfAdvice) {
+                this.classNameOfAdvice = classNameOfAdvice;
+                return this;
+            }
+
+            /**
+             * Build constructor point configuration.
+             *
+             * @return plugin advice builder.
+             */
+            public Builder build() {
+                builder.constructorPoints.add(new ConstructorPoint(matcher, 
classNameOfAdvice));
+                return builder;
+            }
+        }
+    }
+}
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
new file mode 100644
index 0000000..7a7f548
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
@@ -0,0 +1,95 @@
+/*
+ * 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 lombok.SneakyThrows;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Plugins loader.
+ * TODO not-implemented yet
+ */
+public class PluginLoader extends ClassLoader {
+
+    private final ConcurrentHashMap<String, Object> objectPool = new 
ConcurrentHashMap<>();
+
+    private final ReentrantLock lock = new ReentrantLock();
+
+    /**
+     * To find all intercepting target classes then to build TypeMatcher.
+     *
+     * @return type matcher
+     */
+    public ElementMatcher<? super TypeDescription> typeMatcher() {
+        return null;
+    }
+
+    /**
+     * To detect the type whether or not exists.
+     *
+     * @param typeDescription TypeDescription
+     * @return contains when it is true.
+     */
+    public boolean containsType(final TypeDescription typeDescription) {
+        return false;
+    }
+
+    /**
+     * Load the definition configuration by TypeDescription.
+     *
+     * @param typeDescription TypeDescription
+     * @return the plugin definition configurations.
+     */
+    public PluginAdviceDefine loadPluginAdviceDefine(final TypeDescription 
typeDescription) {
+        return null;
+    }
+
+    /**
+     * 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.
+     * @return instance of advice
+     */
+    @SneakyThrows({ClassNotFoundException.class, IllegalAccessException.class, 
InstantiationException.class})
+    public <T> T getInstance(final String classNameOfAdvice) {
+
+        if (objectPool.containsKey(classNameOfAdvice)) {
+            return (T) objectPool.get(classNameOfAdvice);
+        }
+
+        lock.lock();
+        try {
+            Object inst = objectPool.get(classNameOfAdvice);
+            if (Objects.isNull(inst)) {
+                inst = Class.forName(classNameOfAdvice, true, this)
+                        .newInstance();
+                objectPool.put(classNameOfAdvice, inst);
+            }
+            return (T) inst;
+        } finally {
+            lock.unlock();
+        }
+    }
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorAdvice.java
similarity index 50%
copy from 
shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
copy to 
shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorAdvice.java
index 817fe08..560f4ad 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorAdvice.java
@@ -16,28 +16,18 @@
  *
  */
 
-package org.apache.shardingsphere.agent.bootstrap;
-
-import java.io.IOException;
-import java.lang.instrument.Instrumentation;
-import org.apache.shardingsphere.agent.core.config.AgentConfiguration;
-import org.apache.shardingsphere.agent.core.config.AgentConfigurationLoader;
-import org.apache.shardingsphere.agent.core.utils.SingletonHolder;
+package org.apache.shardingsphere.agent.core.plugin.advice;
 
 /**
- * ShardingSphere agent.
+ * Weaving the advice around the constructor of target class.
  */
-public class ShardingSphereAgent {
-    
+public interface ConstructorAdvice {
+
     /**
-     * Premain for instrumentation.
+     * Intercept the target's constructor. This method is weaved after the 
constructor execution.
      *
-     * @param agentArgs agent args
-     * @param instrumentation instrumentation
-     * @throws IOException IO exception
+     * @param target intercepted target object
+     * @param args all arguments of the intercepted constructor
      */
-    public static void premain(final String agentArgs, final Instrumentation 
instrumentation) throws IOException {
-        AgentConfiguration agentConfiguration = 
AgentConfigurationLoader.load();
-        SingletonHolder.INSTANCE.put(agentConfiguration);
-    }
+    void onConstructor(TargetObject target, Object[] args);
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorMethodInterceptor.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorMethodInterceptor.java
new file mode 100644
index 0000000..dfa3916
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/ConstructorMethodInterceptor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.advice;
+
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.implementation.bind.annotation.This;
+
+/**
+ * Proxy class for ByteBuddy to intercept methods of target and weave 
post-method after constructor.
+ */
+@Slf4j
+public class ConstructorMethodInterceptor {
+    private final ConstructorAdvice advice;
+
+    public ConstructorMethodInterceptor(final ConstructorAdvice advice) {
+        this.advice = advice;
+    }
+
+    /**
+     * Intercept constructor.
+     *
+     * @param target the target object
+     * @param args the all constructor arguments
+     */
+    @RuntimeType
+    public void intercept(final @This TargetObject target, final @AllArguments 
Object[] args) {
+        try {
+            advice.onConstructor(target, args);
+            // CHECKSTYLE:OFF
+        } catch (Throwable throwable) {
+            // CHECKSTYLE:ON
+            log.error("Constructor advice execution error. class: {}", 
target.getClass().getTypeName(), throwable);
+        }
+    }
+
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundAdvice.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundAdvice.java
new file mode 100644
index 0000000..cb43791
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundAdvice.java
@@ -0,0 +1,57 @@
+/*
+ * 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.advice;
+
+import java.lang.reflect.Method;
+
+/**
+ * Weaving the advice around the target method.
+ */
+public interface MethodAroundAdvice {
+
+    /**
+     * Intercept the target method and weave the method before origin method. 
It will invoke before the origin calling.
+     *
+     * @param target the target object
+     * @param method the target method
+     * @param args all method arguments
+     * @param result wrapped class of result to detect whether or not to 
execute the origin method.
+     */
+    void beforeMethod(TargetObject target, Method method, Object[] args, 
MethodInvocationResult result);
+
+    /**
+     * Intercept the target method and weave the method after origin method.  
It will invoke after the origin calling.
+     *
+     * @param target the target object
+     * @param method the target method
+     * @param args all method arguments
+     * @param result wrapped class of result to detect whether or not to 
execute the origin method.
+     */
+    void afterMethod(TargetObject target, Method method, Object[] args, 
MethodInvocationResult result);
+
+    /**
+     * Weaving the method after origin method throwing.
+     *
+     * @param target the target object
+     * @param method the target method
+     * @param args all method arguments
+     * @param throwable exception from target method.
+     */
+    void onThrowing(TargetObject target, Method method, Object[] args, 
Throwable throwable);
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundInterceptor.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundInterceptor.java
new file mode 100644
index 0000000..123f50e
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodAroundInterceptor.java
@@ -0,0 +1,96 @@
+/*
+ * 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.advice;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.implementation.bind.annotation.SuperCall;
+import net.bytebuddy.implementation.bind.annotation.This;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+/**
+ * Proxy class for ByteBuddy to intercept methods of target and weave pre- and 
post-method around the target method.
+ */
+@Slf4j
+public class MethodAroundInterceptor {
+    private final MethodAroundAdvice advice;
+
+    public MethodAroundInterceptor(final MethodAroundAdvice advice) {
+        this.advice = advice;
+    }
+
+    /**
+     * Only intercept instance method.
+     *
+     * @param target the target object
+     * @param method the intercepted method
+     * @param args the all arguments of method
+     * @param uber the origin method invocation
+     * @return the return value of target invocation
+     */
+    @RuntimeType
+    @SneakyThrows
+    public Object intercept(final @This Object target, final @Origin Method 
method, final @AllArguments Object[] args, final @SuperCall Callable<?> uber) {
+        final TargetObject instance = (TargetObject) target;
+        final MethodInvocationResult result = new MethodInvocationResult();
+
+        Object ret;
+
+        try {
+            advice.beforeMethod(instance, method, args, result);
+            // CHECKSTYLE:OFF
+        } catch (Throwable throwable) {
+            // CHECKSTYLE:ON
+            log.error("Failed to execute the pre-method of method[{}] in 
class[{}].", method.getName(), target.getClass(), throwable);
+        }
+
+        try {
+            if (result.isRebased()) {
+                ret = result.getResult();
+            } else {
+                ret = uber.call();
+            }
+            // CHECKSTYLE:OFF
+        } catch (Throwable throwable) {
+            // CHECKSTYLE:ON
+            try {
+                advice.onThrowing(instance, method, args, throwable);
+                // CHECKSTYLE:OFF
+            } catch (Throwable adviceException) {
+                // CHECKSTYLE:ON
+                log.error("Failed to execute the error handler of method[{}] 
in class[{}].", method.getName(), target.getClass(), adviceException);
+            }
+            throw throwable;
+        } finally {
+            try {
+                advice.afterMethod(instance, method, args, result);
+                // CHECKSTYLE:OFF
+            } catch (Throwable throwable) {
+                // CHECKSTYLE:ON
+                log.error("Failed to execute the post-method of method[{}] in 
class[{}].", method.getName(), target.getClass(), throwable);
+            }
+        }
+        return ret;
+    }
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodInvocationResult.java
similarity index 50%
copy from 
shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
copy to 
shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodInvocationResult.java
index 817fe08..fea7038 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/MethodInvocationResult.java
@@ -16,28 +16,42 @@
  *
  */
 
-package org.apache.shardingsphere.agent.bootstrap;
-
-import java.io.IOException;
-import java.lang.instrument.Instrumentation;
-import org.apache.shardingsphere.agent.core.config.AgentConfiguration;
-import org.apache.shardingsphere.agent.core.config.AgentConfigurationLoader;
-import org.apache.shardingsphere.agent.core.utils.SingletonHolder;
+package org.apache.shardingsphere.agent.core.plugin.advice;
 
 /**
- * ShardingSphere agent.
+ * The advice method invocation result.
  */
-public class ShardingSphereAgent {
-    
+public class MethodInvocationResult {
+    private boolean isRebased;
+
+    private Object result;
+
+    /**
+     * To replace the origin result.
+     *
+     * @param result rebase the origin result
+     */
+    public void rebase(final Object result) {
+        isRebased = true;
+        this.result = result;
+    }
+
     /**
-     * Premain for instrumentation.
+     * Whether or not to discard origin method.
      *
-     * @param agentArgs agent args
-     * @param instrumentation instrumentation
-     * @throws IOException IO exception
+     * @return to replace the origin result if true.
      */
-    public static void premain(final String agentArgs, final Instrumentation 
instrumentation) throws IOException {
-        AgentConfiguration agentConfiguration = 
AgentConfigurationLoader.load();
-        SingletonHolder.INSTANCE.put(agentConfiguration);
+    public boolean isRebased() {
+        return isRebased;
     }
+
+    /**
+     * Result that is provided by per-method advice.
+     *
+     * @return the advice result.
+     */
+    public Object getResult() {
+        return result;
+    }
+
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/OverrideArgsInvoker.java
similarity index 50%
copy from 
shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
copy to 
shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/OverrideArgsInvoker.java
index 817fe08..cc1f2fc 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/OverrideArgsInvoker.java
@@ -16,28 +16,19 @@
  *
  */
 
-package org.apache.shardingsphere.agent.bootstrap;
-
-import java.io.IOException;
-import java.lang.instrument.Instrumentation;
-import org.apache.shardingsphere.agent.core.config.AgentConfiguration;
-import org.apache.shardingsphere.agent.core.config.AgentConfigurationLoader;
-import org.apache.shardingsphere.agent.core.utils.SingletonHolder;
+package org.apache.shardingsphere.agent.core.plugin.advice;
 
 /**
- * ShardingSphere agent.
+ * Super(origin) method invoker for ByteBuddy only.
  */
-public class ShardingSphereAgent {
-    
+public interface OverrideArgsInvoker {
+
     /**
-     * Premain for instrumentation.
+     * Invocation origin method.
      *
-     * @param agentArgs agent args
-     * @param instrumentation instrumentation
-     * @throws IOException IO exception
+     * @param args the origin method arguments.
+     * @return the result of the origin method.
      */
-    public static void premain(final String agentArgs, final Instrumentation 
instrumentation) throws IOException {
-        AgentConfiguration agentConfiguration = 
AgentConfigurationLoader.load();
-        SingletonHolder.INSTANCE.put(agentConfiguration);
-    }
+    Object call(Object[] args);
+
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundAdvice.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundAdvice.java
new file mode 100644
index 0000000..602ac41
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundAdvice.java
@@ -0,0 +1,57 @@
+/*
+ * 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.advice;
+
+import java.lang.reflect.Method;
+
+/**
+ * Weaving the advice around the static methods of target class.
+ */
+public interface StaticMethodAroundAdvice {
+
+    /**
+     * Intercept the target method and weave the method before origin method. 
It will invoke before the origin calling.
+     *
+     * @param klass the target class
+     * @param method the target method
+     * @param args all method arguments
+     * @param result wrapped class of result to detect whether or not to 
execute the origin method.
+     */
+    void beforeMethod(Class<?> klass, Method method, Object[] args, 
MethodInvocationResult result);
+
+    /**
+     * Intercept the target method and weave the method after origin method. 
It will invoke after the origin calling.
+     *
+     * @param klass the target class
+     * @param method the target method
+     * @param args all method arguments
+     * @param result wrapped class of result to detect whether or not to 
execute the origin method.
+     */
+    void afterMethod(Class<?> klass, Method method, Object[] args, 
MethodInvocationResult result);
+
+    /**
+     * Weaving the method after origin method throwing.
+     *
+     * @param klass the target class
+     * @param method the target method
+     * @param args all method arguments
+     * @param throwable exception from target method.
+     */
+    void onThrowing(Class<?> klass, Method method, Object[] args, Throwable 
throwable);
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundInterceptor.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundInterceptor.java
new file mode 100644
index 0000000..32078ae
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/StaticMethodAroundInterceptor.java
@@ -0,0 +1,94 @@
+/*
+ * 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.advice;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.implementation.bind.annotation.SuperCall;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+/**
+ * Proxy class for ByteBuddy to intercept methods of target and weave pre- and 
post-method around the target method.
+ */
+@Slf4j
+public class StaticMethodAroundInterceptor {
+
+    private final StaticMethodAroundAdvice advice;
+
+    public StaticMethodAroundInterceptor(final StaticMethodAroundAdvice 
advice) {
+        this.advice = advice;
+    }
+
+    /**
+     * Only intercept static method.
+     *
+     * @param klass the class of target
+     * @param method the intercepted method
+     * @param args the all arguments of method
+     * @param uber the origin method invocation
+     * @return the return value of target invocation
+     */
+    @RuntimeType
+    @SneakyThrows
+    public Object intercept(final @Origin Class<?> klass, final @Origin Method 
method, final @AllArguments Object[] args, final @SuperCall Callable<?> uber) {
+        final MethodInvocationResult result = new MethodInvocationResult();
+        final Object ret;
+
+        try {
+            advice.afterMethod(klass, method, args, result);
+            // CHECKSTYLE:OFF
+        } catch (Throwable throwable) {
+            // CHECKSTYLE:ON
+            log.error("Failed to execute the pre-method of method[{}] in 
class[{}].", method.getName(), klass, throwable);
+        }
+
+        try {
+            if (result.isRebased()) {
+                ret = result.getResult();
+            } else {
+                ret = uber.call();
+            }
+            // CHECKSTYLE:OFF
+        } catch (Throwable throwable) {
+            // CHECKSTYLE:ON
+            try {
+                advice.onThrowing(klass, method, args, throwable);
+                // CHECKSTYLE:OFF
+            } catch (Throwable ignore) {
+                // CHECKSTYLE:ON
+                log.error("Failed to execute the error handler of method[{}] 
in class[{}].", method.getName(), klass, throwable);
+            }
+            throw throwable;
+        } finally {
+            try {
+                advice.beforeMethod(klass, method, args, result);
+                // CHECKSTYLE:OFF
+            } catch (Throwable throwable) {
+                // CHECKSTYLE:ON
+                log.error("Failed to execute the post-method of method[{}] in 
class[{}].", method.getName(), klass, throwable);
+            }
+        }
+        return ret;
+    }
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/TargetObject.java
similarity index 50%
copy from 
shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
copy to 
shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/TargetObject.java
index 817fe08..b959dad 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/advice/TargetObject.java
@@ -16,28 +16,25 @@
  *
  */
 
-package org.apache.shardingsphere.agent.bootstrap;
-
-import java.io.IOException;
-import java.lang.instrument.Instrumentation;
-import org.apache.shardingsphere.agent.core.config.AgentConfiguration;
-import org.apache.shardingsphere.agent.core.config.AgentConfigurationLoader;
-import org.apache.shardingsphere.agent.core.utils.SingletonHolder;
+package org.apache.shardingsphere.agent.core.plugin.advice;
 
 /**
- * ShardingSphere agent.
+ * Wrapped class for target and provide a context to store variable during 
invocation.
  */
-public class ShardingSphereAgent {
-    
+public interface TargetObject {
+
     /**
-     * Premain for instrumentation.
+     * Get the variable from context.
      *
-     * @param agentArgs agent args
-     * @param instrumentation instrumentation
-     * @throws IOException IO exception
+     * @return the attachment.
      */
-    public static void premain(final String agentArgs, final Instrumentation 
instrumentation) throws IOException {
-        AgentConfiguration agentConfiguration = 
AgentConfigurationLoader.load();
-        SingletonHolder.INSTANCE.put(agentConfiguration);
-    }
+    Object getAttachment();
+
+    /**
+     * Store a variable into context.
+     *
+     * @param attachment what variable you want to store.
+     */
+    void setAttachment(Object attachment);
+
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ClassStaticMethodPoint.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ClassStaticMethodPoint.java
new file mode 100644
index 0000000..d15c3b1
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ClassStaticMethodPoint.java
@@ -0,0 +1,68 @@
+/*
+ * 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.point;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+/**
+ * Configuration of static method intercepting point.
+ */
+public class ClassStaticMethodPoint {
+
+    private final ElementMatcher<? super MethodDescription> matcher;
+
+    private final String advice;
+
+    private final boolean overrideArgs;
+
+    public ClassStaticMethodPoint(final ElementMatcher<? super 
MethodDescription> matcher, final String advice, final boolean overrideArgs) {
+        this.matcher = matcher;
+        this.advice = advice;
+        this.overrideArgs = overrideArgs;
+    }
+
+    /**
+     * To detect target method constraints.
+     *
+     * @return constraints
+     */
+    public ElementMatcher<? super MethodDescription> getMethodsMatcher() {
+        return matcher;
+    }
+
+    /**
+     * To get the class name of advice.
+     *
+     * @return the class name of advice.
+     */
+    public String getAdvice() {
+        return advice;
+    }
+
+    /**
+     * To detect whether to override origin arguments.
+     *
+     * @return override if true
+     */
+    public boolean isOverrideArgs() {
+        return overrideArgs;
+    }
+
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ConstructorPoint.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ConstructorPoint.java
new file mode 100644
index 0000000..a64e789
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/ConstructorPoint.java
@@ -0,0 +1,55 @@
+/*
+ * 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.point;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+/**
+ * Configuration of constructor intercepting point.
+ */
+public class ConstructorPoint {
+    private final ElementMatcher<? super MethodDescription> matcher;
+
+    private final String advice;
+
+    public ConstructorPoint(final ElementMatcher<? super MethodDescription> 
matcher, final String advice) {
+        this.matcher = matcher;
+        this.advice = advice;
+    }
+
+    /**
+     * To detect target constructor constraints.
+     *
+     * @return constraints
+     */
+    public ElementMatcher<? super MethodDescription> getConstructorMatcher() {
+        return matcher;
+    }
+
+    /**
+     * To get the class name of advice.
+     *
+     * @return the class name of advice.
+     */
+    public String getAdvice() {
+        return advice;
+    }
+
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/InstanceMethodPoint.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/InstanceMethodPoint.java
new file mode 100644
index 0000000..b380023
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/point/InstanceMethodPoint.java
@@ -0,0 +1,66 @@
+/*
+ * 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.point;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+/**
+ * Configuration of instance method intercepting point.
+ */
+public class InstanceMethodPoint {
+    private final ElementMatcher<? super MethodDescription> matcher;
+
+    private final String advice;
+
+    private final boolean overrideArgs;
+
+    public InstanceMethodPoint(final ElementMatcher<? super MethodDescription> 
matcher, final String advice, final boolean overrideArgs) {
+        this.matcher = matcher;
+        this.advice = advice;
+        this.overrideArgs = overrideArgs;
+    }
+
+    /**
+     * Detecting target method constraints but static methods.
+     *
+     * @return constraints
+     */
+    public ElementMatcher<? super MethodDescription> getMethodMatcher() {
+        return matcher;
+    }
+
+    /**
+     * To get the class name of advice.
+     *
+     * @return the class name of advice.
+     */
+    public String getAdvice() {
+        return advice;
+    }
+
+    /**
+     * To detect whether to override origin arguments.
+     *
+     * @return override if true
+     */
+    public boolean isOverrideArgs() {
+        return overrideArgs;
+    }
+}

Reply via email to