修改源代码动态修改模式,在原有类的基础上,构建拦截器

This commit is contained in:
wusheng 2016-06-12 21:33:37 +08:00
parent f594c99a56
commit 0abd415403
4 changed files with 46 additions and 18 deletions

View File

@ -8,7 +8,6 @@ import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
@ -73,22 +72,14 @@ public class EnhanceClazz4Interceptor {
}
/**
* rename origin class <br/>
* add '$$Origin' at the end of be enhanced classname <br/>
* such as: class com.ai.cloud.TestClass to class
* com.ai.cloud.TestClass$$Origin
* find origin class source code for interceptor
*/
String renameClassName = enhanceOriginClassName + "$$Origin";
Class<?> originClass = new ByteBuddy()
.redefine(resolution.resolve(),
ClassFileLocator.ForClassLoader.ofClassPath())
.name(renameClassName)
.make()
.load(ClassLoader.getSystemClassLoader(),
ClassLoadingStrategy.Default.INJECTION).getLoaded();
DynamicType.Builder<?> newClassBuilder = new ByteBuddy()
.rebase(resolution.resolve(),
ClassFileLocator.ForClassLoader.ofClassPath());
/**
* create a new class using origin classname.<br/>
* alter class source code.<br/>
*
* new class need:<br/>
* 1.add field '_$EnhancedClassInstanceContext' of type
@ -102,8 +93,6 @@ public class EnhanceClazz4Interceptor {
throw new EnhanceException("no IAroundInterceptor instance. ");
}
DynamicType.Builder<?> newClassBuilder = new ByteBuddy().subclass(
originClass, ConstructorStrategy.Default.IMITATE_SUPER_CLASS);
newClassBuilder = newClassBuilder
.defineField(contextAttrName,
EnhancedClassInstanceContext.class)

View File

@ -0,0 +1,36 @@
package test.ai.cloud.bytebuddy;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.pool.TypePool;
public class SimulateMain2 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException {
TypePool typePool = TypePool.Default.ofClassPath();
new ByteBuddy()
.rebase(typePool.describe("test.ai.cloud.bytebuddy.TestClass")
.resolve(),
ClassFileLocator.ForClassLoader.ofClassPath())
.method(named("testA"))
.intercept(MethodDelegation.to(new MethodInterceptor()))
.method(named("testB"))
.intercept(MethodDelegation.to(new MethodInterceptor()))
.constructor(isConstructor())
.intercept(
MethodDelegation.to(new ConstructorInterceptor())
.andThen(SuperMethodCall.INSTANCE))
.make()
.load(ClassLoader.getSystemClassLoader(),
ClassLoadingStrategy.Default.INJECTION).getLoaded();
TestClass t = new TestClass("abc");
System.out.println(t.testA("1"));
}
}

View File

@ -2,9 +2,12 @@ package test.ai.cloud.plugin;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
import com.ai.cloud.skywalking.plugin.TracingBootstrap;
public class PluginMainTest {
@Test
public void testMain() throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException, ClassNotFoundException {

View File

@ -1 +1 @@
test.ai.cloud.matcher.TestMatcherDefine
test.ai.cloud.plugin.TestInterceptorDefine