simple-bytebuddy

操作对象

// 这个对象作为操作工具起点
ByteBuddy byteBuddy = new ByteBuddy();

环境设置

byteBuddy.with(new NamingStrategy() {
            private final String genericPrefix = "com.godme.bytebuddy.";
            public String subclass(TypeDescription.Generic generic) {
                return genericPrefix +"subclass."+ generic.getTypeName();
            }

            public String redefine(TypeDescription typeDescription) {
                return genericPrefix + "redefine." + typeDescription.getSimpleName();
            }

            public String rebase(TypeDescription typeDescription) {
                return genericPrefix + "rebase." + typeDescription.getSimpleName();
            }
        });

通过with方法,可以进行环境设置,在关注的方面进行特殊的指定。

出生世家

// 类不能,至少不应该,忘记自己的出身
DynamicType.Builder<Object> dynamicTypeBuilder = bytebuddy.subclass(Object.class);

基于使用的场景,会有这三种方式

operationdescription
subclass创建一个继承类,添加方法或重写
redefine重定义一个类,可以增加或者删除方法,非此即彼
rebase重定义一个类,修改的操作会和原来的操作融合,不会覆盖或丢失

养父养母

// 是否继承了接口
dynamicTypeBuilder.implement(Serializable.class);

名称限定

// 哪一个类
dynamicTypeBuilder.name("com.godme.Person");

方法限定

// ElementMatcher
// 哪一个方法,获取定义工具类
DynamicType.Builder.MethodDefinition.ImplementationDefinition<Object> toStringDefinition = dynamicBuilder.method(named("toString"));
matcherdescription
named叫啥
returns回啥
takesArguments传啥
isDeclaredBy谁的
isAnnotatedWith帽子

更多方法自行发觉

#内容替换

  • 简单值返回
// 拦截设置固定值
toStringDefinition.intercept(FixedValue.value("person"));
  • 委托处理
// MethodDelegation委托给Dog,调用同签名方法
toStringDefinition.intercept(MethodDelegation.to(Dog.class));

属性修改

dynamicTypeBuilder.define();// 万能改造
  • field
  • method
  • constructor

灵魂重造

// 根据前面的定制信息,自动构建底层字节码和相关信息,并封装为对象
DynamicType.UnLoaded<Object> unLoadedDynamicType = dynamicTypeBuilder.make();

投胎转世

// JVM加载
DynamicType.Loaded<Object> loadedDynamicType = unLoadedDynamicType.load(getClass().getClassLoader());
// DynamicType.Loaded<Object> loadedDynamicType = unLoadedDynamicType.load(
//   getClass().getClassLoader(),
//	ClassLoadingStrategy.Default.CHILD_FIRST);
strategydescription
ClassLoadingStrategy.Default.WRAPPER新包装classloader
ClassLoadingStrategy.Default.CHILD_FIRST子类优先
ClassLoadingStrategy.Default.INJECTION反射注入

今夕何夕

// JVM加载过的类
Class<?> dynamicTypeClass = loadedDynamicType.getLoaded();

代理一下

public class ToStringAgent {

    public static void premain(String args, Instrumentation instrumentation){
        new AgentBuilder.Default()
                .type(isAnnotatedWith(ToString.class))
                .transform(new AgentBuilder.Transformer(){

                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
                        builder.method(named("toString").and(ElementMatchers.returns(String.class)))
                                .intercept(FixedValue.value("啊哈,啥也看不到!"));
                        return null;
                    }
                }).installOn(instrumentation);
    }
}
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页