You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2021/09/25 05:18:16 UTC
[shardingsphere] branch master updated: Add override argument
interceptor (#12684)
This is an automated email from the ASF dual-hosted git repository.
zhangliang 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 5b31bd6 Add override argument interceptor (#12684)
5b31bd6 is described below
commit 5b31bd6d3107f8bf8c4aae2f0908ca9eba33aecf
Author: Dachuan J <46...@users.noreply.github.com>
AuthorDate: Sat Sep 25 13:17:35 2021 +0800
Add override argument interceptor (#12684)
* Add override argument interceptor
* Fix code style
---
.../transformer/ShardingSphereTransformer.java | 44 +++++++--
.../ClassStaticMethodInterceptorArgsOverride.java | 102 ++++++++++++++++++++
.../InstanceMethodInterceptorArgsOverride.java | 105 +++++++++++++++++++++
...seClassStaticMethodInterceptorArgsOverride.java | 31 ++++++
...mposeInstanceMethodInterceptorArgsOverride.java | 30 ++++++
5 files changed, 305 insertions(+), 7 deletions(-)
diff --git a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/bytebuddy/transformer/ShardingSphereTransformer.java b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/bytebuddy/transformer/ShardingSphereTransformer.java
index fca066b..96c6420 100644
--- a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/bytebuddy/transformer/ShardingSphereTransformer.java
+++ b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/bytebuddy/transformer/ShardingSphereTransformer.java
@@ -39,11 +39,15 @@ import org.apache.shardingsphere.agent.api.point.InstanceMethodPoint;
import org.apache.shardingsphere.agent.api.point.PluginInterceptorPoint;
import org.apache.shardingsphere.agent.core.plugin.PluginLoader;
import org.apache.shardingsphere.agent.core.plugin.interceptor.ClassStaticMethodAroundInterceptor;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.ClassStaticMethodInterceptorArgsOverride;
import org.apache.shardingsphere.agent.core.plugin.interceptor.ConstructorInterceptor;
import org.apache.shardingsphere.agent.core.plugin.interceptor.InstanceMethodAroundInterceptor;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.InstanceMethodInterceptorArgsOverride;
import org.apache.shardingsphere.agent.core.plugin.interceptor.compose.ComposeClassStaticMethodAroundInterceptor;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.compose.ComposeClassStaticMethodInterceptorArgsOverride;
import org.apache.shardingsphere.agent.core.plugin.interceptor.compose.ComposeConstructorInterceptor;
import org.apache.shardingsphere.agent.core.plugin.interceptor.compose.ComposeInstanceMethodAroundInterceptor;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.compose.ComposeInstanceMethodInterceptorArgsOverride;
import java.util.Collection;
import java.util.LinkedList;
@@ -86,7 +90,7 @@ public final class ShardingSphereTransformer implements Transformer {
if (constructorPointList.isEmpty()) {
return null;
}
- if (constructorPointList.size() == 1) {
+ if (1 == constructorPointList.size()) {
return new ShardingSphereTransformationPoint<>(methodDescription, new ConstructorInterceptor(pluginLoader.getOrCreateInstance(constructorPointList.get(0).getAdvice())));
} else {
List<ConstructorAdvice> constructorAdvices = constructorPointList.stream()
@@ -137,16 +141,30 @@ public final class ShardingSphereTransformer implements Transformer {
if (classStaticMethodPoints.isEmpty()) {
return null;
}
- if (classStaticMethodPoints.size() == 1) {
- return new ShardingSphereTransformationPoint<>(methodDescription, new ClassStaticMethodAroundInterceptor(pluginLoader.getOrCreateInstance(classStaticMethodPoints.get(0).getAdvice())));
+ if (1 == classStaticMethodPoints.size()) {
+ if (classStaticMethodPoints.get(0).isOverrideArgs()) {
+ return new ShardingSphereTransformationPoint<>(methodDescription,
+ new ClassStaticMethodInterceptorArgsOverride(pluginLoader.getOrCreateInstance(classStaticMethodPoints.get(0).getAdvice())));
+ } else {
+ return new ShardingSphereTransformationPoint<>(methodDescription,
+ new ClassStaticMethodAroundInterceptor(pluginLoader.getOrCreateInstance(classStaticMethodPoints.get(0).getAdvice())));
+ }
} else {
Collection<ClassStaticMethodAroundAdvice> classStaticMethodAroundAdvices = new LinkedList<>();
+ boolean isArgsOverride = false;
for (ClassStaticMethodPoint point : classStaticMethodPoints) {
+ if (point.isOverrideArgs()) {
+ isArgsOverride = true;
+ }
if (null != point.getAdvice()) {
classStaticMethodAroundAdvices.add(pluginLoader.getOrCreateInstance(point.getAdvice()));
}
}
- return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeClassStaticMethodAroundInterceptor(classStaticMethodAroundAdvices));
+ if (isArgsOverride) {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeClassStaticMethodInterceptorArgsOverride(classStaticMethodAroundAdvices));
+ } else {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeClassStaticMethodAroundInterceptor(classStaticMethodAroundAdvices));
+ }
}
}
@@ -175,16 +193,28 @@ public final class ShardingSphereTransformer implements Transformer {
if (instanceMethodPoints.isEmpty()) {
return null;
}
- if (instanceMethodPoints.size() == 1) {
- return new ShardingSphereTransformationPoint<>(methodDescription, new InstanceMethodAroundInterceptor(pluginLoader.getOrCreateInstance(instanceMethodPoints.get(0).getAdvice())));
+ if (1 == instanceMethodPoints.size()) {
+ if (instanceMethodPoints.get(0).isOverrideArgs()) {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new InstanceMethodInterceptorArgsOverride(pluginLoader.getOrCreateInstance(instanceMethodPoints.get(0).getAdvice())));
+ } else {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new InstanceMethodAroundInterceptor(pluginLoader.getOrCreateInstance(instanceMethodPoints.get(0).getAdvice())));
+ }
} else {
Collection<InstanceMethodAroundAdvice> instanceMethodAroundAdvices = new LinkedList<>();
+ boolean isArgsOverride = false;
for (InstanceMethodPoint point : instanceMethodPoints) {
+ if (point.isOverrideArgs()) {
+ isArgsOverride = true;
+ }
if (null != point.getAdvice()) {
instanceMethodAroundAdvices.add(pluginLoader.getOrCreateInstance(point.getAdvice()));
}
}
- return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeInstanceMethodAroundInterceptor(instanceMethodAroundAdvices));
+ if (isArgsOverride) {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeInstanceMethodInterceptorArgsOverride(instanceMethodAroundAdvices));
+ } else {
+ return new ShardingSphereTransformationPoint<>(methodDescription, new ComposeInstanceMethodAroundInterceptor(instanceMethodAroundAdvices));
+ }
}
}
}
diff --git a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/ClassStaticMethodInterceptorArgsOverride.java b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/ClassStaticMethodInterceptorArgsOverride.java
new file mode 100644
index 0000000..8d6bf6d
--- /dev/null
+++ b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/ClassStaticMethodInterceptorArgsOverride.java
@@ -0,0 +1,102 @@
+/*
+ * 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.interceptor;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Morph;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import org.apache.shardingsphere.agent.api.advice.ClassStaticMethodAroundAdvice;
+import org.apache.shardingsphere.agent.api.advice.OverrideArgsInvoker;
+import org.apache.shardingsphere.agent.api.result.MethodInvocationResult;
+import org.apache.shardingsphere.agent.core.plugin.PluginContext;
+
+import java.lang.reflect.Method;
+
+/**
+ * Proxy class for ByteBuddy to intercept methods of target and weave pre- and post-method around the target method with args override.
+ */
+@RequiredArgsConstructor
+@Slf4j
+public class ClassStaticMethodInterceptorArgsOverride {
+
+ private final ClassStaticMethodAroundAdvice classStaticMethodAroundAdvice;
+
+ private boolean needCall = true;
+
+ /**
+ * Only intercept static method.
+ *
+ * @param klass the class of target
+ * @param method the intercepted method
+ * @param args the all arguments of method
+ * @param callable the origin method invocation
+ * @return the return value of target invocation
+ */
+ @RuntimeType
+ @SneakyThrows
+ public Object intercept(@Origin final Class<?> klass, @Origin final Method method, @AllArguments final Object[] args, @Morph final OverrideArgsInvoker callable) {
+ MethodInvocationResult methodResult = new MethodInvocationResult();
+ Object result;
+ needCall = classStaticMethodAroundAdvice.disableCheck() || PluginContext.isPluginEnabled();
+ try {
+ if (needCall) {
+ classStaticMethodAroundAdvice.beforeMethod(klass, method, args, methodResult);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the pre-method of method[{}] in class[{}]", method.getName(), klass, ex);
+ }
+ try {
+ if (methodResult.isRebased()) {
+ result = methodResult.getResult();
+ } else {
+ result = callable.call(args);
+ }
+ methodResult.rebase(result);
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ try {
+ if (needCall) {
+ classStaticMethodAroundAdvice.onThrowing(klass, method, args, ex);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ignored) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the error handler of method[{}] in class[{}]", method.getName(), klass, ex);
+ }
+ throw ex;
+ } finally {
+ try {
+ if (needCall) {
+ classStaticMethodAroundAdvice.afterMethod(klass, method, args, methodResult);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the post-method of method[{}] in class[{}]", method.getName(), klass, ex);
+ }
+ }
+ return methodResult.isRebased() ? methodResult.getResult() : result;
+ }
+}
diff --git a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/InstanceMethodInterceptorArgsOverride.java b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/InstanceMethodInterceptorArgsOverride.java
new file mode 100644
index 0000000..38d78c1
--- /dev/null
+++ b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/InstanceMethodInterceptorArgsOverride.java
@@ -0,0 +1,105 @@
+/*
+ * 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.interceptor;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Morph;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.implementation.bind.annotation.This;
+import org.apache.shardingsphere.agent.api.advice.AdviceTargetObject;
+import org.apache.shardingsphere.agent.api.advice.InstanceMethodAroundAdvice;
+import org.apache.shardingsphere.agent.api.advice.OverrideArgsInvoker;
+import org.apache.shardingsphere.agent.api.result.MethodInvocationResult;
+import org.apache.shardingsphere.agent.core.plugin.PluginContext;
+
+import java.lang.reflect.Method;
+
+/**
+ * Proxy class for ByteBuddy to intercept methods of target and weave pre- and post-method around the target method with args override.
+ */
+@RequiredArgsConstructor
+@Slf4j
+public class InstanceMethodInterceptorArgsOverride {
+
+ private final InstanceMethodAroundAdvice instanceMethodAroundAdvice;
+
+ private boolean needCall = true;
+
+ /**
+ * Only intercept instance method.
+ *
+ * @param target the target object
+ * @param method the intercepted method
+ * @param args the all arguments of method
+ * @param callable the origin method invocation
+ * @return the return value of target invocation
+ */
+ @RuntimeType
+ @SneakyThrows
+ public Object intercept(@This final Object target, @Origin final Method method, @AllArguments final Object[] args, @Morph final OverrideArgsInvoker callable) {
+ AdviceTargetObject instance = (AdviceTargetObject) target;
+ MethodInvocationResult methodResult = new MethodInvocationResult();
+ Object result;
+ needCall = instanceMethodAroundAdvice.disableCheck() || PluginContext.isPluginEnabled();
+ try {
+ if (needCall) {
+ instanceMethodAroundAdvice.beforeMethod(instance, method, args, methodResult);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the pre-method of method[{}] in class[{}]", method.getName(), target.getClass(), ex);
+ }
+ try {
+ if (methodResult.isRebased()) {
+ result = methodResult.getResult();
+ } else {
+ result = callable.call(args);
+ }
+ methodResult.rebase(result);
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ try {
+ if (needCall) {
+ instanceMethodAroundAdvice.onThrowing(instance, method, args, ex);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ignored) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the error handler of method[{}] in class[{}]", method.getName(), target.getClass(), ex);
+ }
+ throw ex;
+ } finally {
+ try {
+ if (needCall) {
+ instanceMethodAroundAdvice.afterMethod(instance, method, args, methodResult);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable ex) {
+ // CHECKSTYLE:ON
+ log.error("Failed to execute the post-method of method[{}] in class[{}]", method.getName(), target.getClass(), ex);
+ }
+ }
+ return methodResult.isRebased() ? methodResult.getResult() : result;
+ }
+}
diff --git a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeClassStaticMethodInterceptorArgsOverride.java b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeClassStaticMethodInterceptorArgsOverride.java
new file mode 100644
index 0000000..c5ec833
--- /dev/null
+++ b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeClassStaticMethodInterceptorArgsOverride.java
@@ -0,0 +1,31 @@
+/*
+ * 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.interceptor.compose;
+
+import org.apache.shardingsphere.agent.api.advice.ClassStaticMethodAroundAdvice;
+import org.apache.shardingsphere.agent.core.bytebuddy.transformer.advice.ComposeClassStaticMethodAroundAdvice;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.ClassStaticMethodInterceptorArgsOverride;
+
+import java.util.Collection;
+
+public final class ComposeClassStaticMethodInterceptorArgsOverride extends ClassStaticMethodInterceptorArgsOverride {
+
+ public ComposeClassStaticMethodInterceptorArgsOverride(final Collection<ClassStaticMethodAroundAdvice> instanceMethodAroundAdvices) {
+ super(new ComposeClassStaticMethodAroundAdvice(instanceMethodAroundAdvices));
+ }
+}
diff --git a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeInstanceMethodInterceptorArgsOverride.java b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeInstanceMethodInterceptorArgsOverride.java
new file mode 100644
index 0000000..95a239f
--- /dev/null
+++ b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/interceptor/compose/ComposeInstanceMethodInterceptorArgsOverride.java
@@ -0,0 +1,30 @@
+/*
+ * 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.interceptor.compose;
+
+import org.apache.shardingsphere.agent.api.advice.InstanceMethodAroundAdvice;
+import org.apache.shardingsphere.agent.core.bytebuddy.transformer.advice.ComposeInstanceMethodAroundAdvice;
+import org.apache.shardingsphere.agent.core.plugin.interceptor.InstanceMethodInterceptorArgsOverride;
+
+import java.util.Collection;
+
+public class ComposeInstanceMethodInterceptorArgsOverride extends InstanceMethodInterceptorArgsOverride {
+ public ComposeInstanceMethodInterceptorArgsOverride(final Collection<InstanceMethodAroundAdvice> instanceMethodAroundAdvices) {
+ super(new ComposeInstanceMethodAroundAdvice(instanceMethodAroundAdvices));
+ }
+}