You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Quarkus中用Gizmo实现类方法复制及解决注入NPE问题

问题说明

我有如下核心接口与实现类,用户可通过扩展核心接口来获得CRUD方法。现在在使用Quarkus Gizmo生成自定义Repository的实现类时遇到两个问题,寻求解决方案:

核心代码

JRepository接口

public interface JRepository<E, ID> {

    // sqlClient
    JSqlClient sql();

    // crud methods
    E findNullable(ID id);

    List<E> findByIds(Iterable<ID> ids);
}

JRepositoryImpl实现类

public class JRepositoryImpl<E, ID> implements JRepository<E, ID> {
    @Override
    public JSqlClient sql() {
        return sqlClient; // 返回sqlClient实例
    }

    @Override
    public E findNullable(ID id) {
        // 自定义逻辑
        return sql().findById(id);
    }

    @Override
    public List<E> findByIds(Iterable<ID> ids) {
        // 自定义逻辑
        return sql().findByIds(ids);
    }
}

用户自定义Repository示例

用户只需扩展JRepository即可获得CRUD方法:

public interface TestRepository extends JRepository<Book, Long> {
}

当前字节码生成相关代码

生成的TestRepository实现类

通过字节码生成的实现类如下:

@ApplicationScoped
@Unremovable
public class TestRepository_edb259d1f267785b946cb0bcfd7d69d6e7653180Impl implements TestRepository {
    private final TestInterface defaultImpl;

    public TestRepository_edb259d1f267785b946cb0bcfd7d69d6e7653180Impl() {
    }

    public TestRepository_edb259d1f267785b946cb0bcfd7d69d6e7653180Impl(JSqlClient var1) {
        ClassLoader var2 = Thread.currentThread().getContextClassLoader();
        Class var3 = Class.forName("com.Book", false, var2);
        TestInterfaceImpl var4 = new TestInterfaceImpl(var1, var3);
        this.defaultImpl = (TestInterface)var4;
    }

    public Object findNullable(Object var1) {
        return this.defaultImpl.findNullable(var1);
    }

    public Class entityType() {
        return this.defaultImpl.entityType();
    }

    public JSqlClient sql() {
        return this.defaultImpl.sql();
    }
}

TestInterfaceImpl类

public class TestInterfaceImpl<E, ID> implements TestInterface<E, ID> {

    protected final JSqlClientImplementor sqlClient;

    protected final Class<E> entityType;

    protected TestInterfaceImpl(JSqlClient sqlClient) {
        this(sqlClient, null);
    }

    public TestInterfaceImpl(JSqlClient sqlClient, Class<E> entityType) {
        this.sqlClient = Utils.validateSqlClient(sqlClient);
        this.entityType = entityType;
    }

    @Override
    public JSqlClient sql() {
        return sqlClient;
    }

    @Override
    public Class<E> entityType() {
        return entityType;
    }

    @Override
    public E findNullable(ID id) {
        return sqlClient.getEntities().findById(entityType, id);
    }
}

待解决问题

  1. Gizmo方法体复制问题:使用Gizmo的ClassCreator、MethodCreator等API生成自定义Repository实现时,无法直接复制JRepositoryImpl中的方法体逻辑。是否必须使用底层的ClassVisitor和MethodVisitor?有没有更优的实现方案,或者可参考的同类代码?

  2. 注入空指针问题:Quarkus注入生成的TestRepository实现类时抛出错误:

    Caused by: java.lang.NullPointerException: Cannot invoke "TestInterface.findNullable(Object)" because "this.defaultImpl" is null
    

    如何解决这个空指针问题?

内容的提问来源于stack exchange,提问作者Hydra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:57:15