gpt4 book ai didi

java - 如何使用 Byte Buddy 创建默认构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:25:00 31 4
gpt4 key购买 nike

我想拦截对我的一个类的一些方法调用,但这些类没有默认构造函数。

给定以下类,我将如何设置 Byte Buddy 以同时创建一个公共(public)无参数构造函数来创建生成的类?

public class GetLoggedInUsersSaga extends AbstractSpaceSingleEventSaga {
private final UserSessionRepository userSessionRepository;

@Inject
public GetLoggedInUsersSaga(final UserSessionRepository userSessionRepository) {
this.userSessionRepository = userSessionRepository;
}

@StartsSaga
public void handle(final GetLoggedInUsersRequest request) {
// this is the method in want to intercept
}
}

编辑:具体用例是简化单元测试设置。
目前我们总是要写这样的东西:

@Test
public void someTest() {
// Given

// When
GetLoggedInUsersRequest request = new GetLoggedInUsersRequest();
setMessageForContext(request); // <-- always do this before calling handle
sut.handle(request);

// Then
}

我认为在@Before 方法中创建一个自动为您设置上下文的代理会很好。

@Before
public void before() {
sut = new GetLoggedInUsersSaga(someDependency);
sut = intercept(sut);
}

@Test
public void someTest() {
// Given

// When
GetLoggedInUsersRequest request = new GetLoggedInUsersRequest();
sut.handle(request);

// Then
}

我玩了一下,但不幸的是我没有让它工作..

public <SAGA extends Saga> SAGA intercept(final SAGA sagaUnderTest) throws NoSuchMethodException, IllegalAccessException, InstantiationException {
return (SAGA) new ByteBuddy()
.subclass(sagaUnderTest.getClass())
.defineConstructor(Collections.<Class<?>>emptyList(), Visibility.PUBLIC)
.intercept(MethodCall.invokeSuper())
.method(ElementMatchers.isAnnotatedWith(StartsSaga.class))
.intercept(
MethodDelegation.to(
new Object() {
@RuntimeType
public Object intercept(
@SuperCall Callable<?> c,
@Origin Method m,
@AllArguments Object[] a) throws Exception {
setMessageForContext((Message) a[0]);
return c.call();
}
}))
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();
}

不幸的是现在我明白了(可能是因为 ctor 调用仍然没有正确设置)

java.lang.IllegalStateException: Cannot invoke public com.frequentis.ps.account.service.audit.GetLoggedInUsersSaga$ByteBuddy$zSZuwhtR() as a super method

这是正确的方法吗?
我应该在这里使用 byte buddy 还是有更简单/其他的方法?

最佳答案

你不能在没有任何字节码的情况下定义构造函数。这将是一个抽象构造函数,这在 Java 中是非法的。我将在未来版本的 javadoc 中添加更精确的描述。感谢您提醒我注意这一点。

您需要定义任何构造函数都需要的 super 方法调用:

DynamicType.Builder builder = ...
builder = builder
.defineConstructor(Collections.<Class<?>>emptyList(), Visibility.PUBLIC)
.intercept(MethodCall
.invoke(superClass.getDeclaredConstructor())
.onSuper())

至于你是否应该在这里使用 Byte Buddy:我不能从我看到的小代码中告诉你。您应该问的问题:考虑到代码量和遵循代码的复杂性,它是否使我的代码更容易?如果 Byte Buddy 使您的代码更易于使用(和运行),请使用它。如果没有,请不要使用它。

关于java - 如何使用 Byte Buddy 创建默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31264748/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com