将 JDBI @BindBean 与 AutoValue 结合使用

vpi*_*mph 5 java reflection jdbi auto-value

TLDR; JDBI@BindBean批注生成一个IllegalAccessExceptionwith AutoValue 生成的类型,因为生成的类型是包私有的,默认情况下无法使用反射访问。

JDBI 是否不灵活,或者是否有通过 AutoValue 的解决方法?(完整问题如下)

快速背景

我正在尝试将 JDBI@BindBean注释与使用 AutoValue 生成源的类型一起使用。

package com.example;

@AutoValue
public abstract class Foo {
  public String getBar();
}
Run Code Online (Sandbox Code Playgroud)

问题是生成的代码如下所示:

package com.example;

@AutoValue
class AutoValue_Foo extends Foo {
  private final String bar;

  @Override
  public String getBar() {
    return this.bar;
  }

  // toString, equals, hashCode
}
Run Code Online (Sandbox Code Playgroud)

注意这个类是包私有的!

现在,如果我尝试使用@BindBean,例如:

@SqlQuery("select * from baz where bar = :foo.bar")
Condition find(@BindBean("foo") Foo foo);
Run Code Online (Sandbox Code Playgroud)

因为AutoValue_Foo是包私有的,并且BindBeanFactory使用反射,如果尝试find使用AutoValue_Foo类型调用,结果是:

java.lang.IllegalAccessException: ... can not access a member of class com.example.Foo with modifiers "public"
Run Code Online (Sandbox Code Playgroud)

相关的 JDBI 代码在这里。我从 Java 反射的角度理解,这可以通过使用解决,setAccessible(true)但这需要 JDBI 的 PR。

所以问题如下:

  1. 有没有办法重构我的代码,我可以在不创建新的 JDBI 映射器的情况下绑定Foo类型AutoValue_Foousing @BindBean

  2. 有没有办法@AutoValue生成 public. 我理解为什么这通常是不可取的(推动人们使用界面而不是实现)。

  3. 是不是BindBeanFactory太不灵活了?它是否应该利用 setAccessible(true)在其原始包之外可用的方法?

vpi*_*mph 5

@BindBeanJDBI 2.71 版本将包含指定使用字段的类型标记的功能type。此类型标记将允许指定用于对提供的参数进行反射调用的类型。

@SqlQuery("select * from baz where bar = :foo.bar") Condition find(@BindBean(value="foo", type=Foo.class) Foo foo);

使用这种技术,您可以消除IllegalAccessException上述问题。