在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); } }
待解决问题
Gizmo方法体复制问题:使用Gizmo的ClassCreator、MethodCreator等API生成自定义Repository实现时,无法直接复制JRepositoryImpl中的方法体逻辑。是否必须使用底层的ClassVisitor和MethodVisitor?有没有更优的实现方案,或者可参考的同类代码?
注入空指针问题:Quarkus注入生成的TestRepository实现类时抛出错误:
Caused by: java.lang.NullPointerException: Cannot invoke "TestInterface.findNullable(Object)" because "this.defaultImpl" is null如何解决这个空指针问题?
内容的提问来源于stack exchange,提问作者Hydra
相关产品推荐
相关产品推荐

