动态镜像类并添加构造函数

时间:2015-01-09 23:14:23

标签: java proxy bytecode java-bytecode-asm cglib

我有一个默认可见性的类,没有任何显式构造函数。我想生成类似的类(使用相同的方法和注释),但使用显式公共默认构造函数。有可能以简单的方式吗?任何现成的代理框架?我担心用cglib手动完成它将是一项相当大的任务

1 个答案:

答案 0 :(得分:1)

cglib将始终覆盖方法而不复制注释。 cglib中的注释不支持,因为它是在Java 5发布之前编写的。

如果您愿意使用与cglib不同的库,请查看我的库Byte Buddy以定义此类构造函数。使用它,您可以定义Java代理以提高原始类的可见性,也可以创建一个子类来指示保留库。

子类的生成方式如下:

DynamicType.Builder<? extends Foo> builder = new ByteBuddy()
  .subclass(Foo.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
  .modifiers(() -> return Foo.class.getModifiers() | Modifiers.PUBLIC);
Foo.class.getDeclaredConstructors().forEach( c ->
  DynamicType.Builder.MethodAnnotationTarget<? extends Foo> target = builder
      .defineConstructor(Arrays.asList(c.getParamaterTypes), 
                         () -> return c.getModifiers() | Modifiers.PUBLIC)
      .intercept(SuperMethodCall.INSTANCE)
      .annotateMethod(c.getAnnotations());
  int index = 0;
  for(Annotation[] a : c.getParameterAnnotatations()) {
    target = target.annotateParameter(index++, a);
  }
  builder = target;
)
Class<? extends Foo> subclass = builder.make()
  .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);

这看起来好像很多代码(我目前正在增强API以缩短它。但你做的是以下内容:

  1. 您定义了Foo的新子类,并指示Byte Buddy不要添加任何构造函数。
  2. 您可以将此类的修饰符定义为Foo的修饰符,但另外为public
  3. 查找Foo声明的所有构造函数,并为每个这样的构造函数,为生成的子类定义新的构造函数。此构造函数定义与Foo的构造函数完全相同的参数类型,并复制修饰符。此外,可见性设置为public
  4. Foo的构造函数的所有注释复制到子类的构造函数中。
  5. 对所有参数注释重复此操作。
  6. 您创建并加载类(在Foo的类加载器上)。