ile bir varsayılan kurucu oluşturmak için nasıl bazı yöntem benim sınıfların birinde çağrıları önünü istiyorum ama bu sınıflar bir varsayılan kurucu yok. Aşağıdaki sınıf Verilen Byte Buddy
, nasıl kurulum Byte Buddy da üretilen sınıfı oluşturmak edebilmek için bir kamu no-argüman yapıcı yaratmak istiyorsunuz?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
}
}
DÜZENLEME: Bunun beton kullanım durumu birim test kurulumunu kolaylaştırmak için. Ben sizin için otomatik olarak bağlam kurar @Before yönteminde bir proxy oluşturmak için güzel olacağını düşündüm
@Test
public void someTest() {
// Given
// When
GetLoggedInUsersRequest request = new GetLoggedInUsersRequest();
setMessageForContext(request); // <-- always do this before calling handle
sut.handle(request);
// Then
}
:
Şu anda hep böyle bir şey yazmak zorunda.
@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
}
Ben biraz etrafında oynanan ama maalesef o
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();
}
Maalesef
şimdi ben (ctor çağırma kurulum düzgün hala olmadığından dolayı) olsun
java.lang.IllegalStateException: Cannot invoke public com.frequentis.ps.account.service.audit.GetLoggedInUsersSaga$ByteBuddy$zSZuwhtR() as a super method
.. çalışma alamadım
Bu doğru yaklaşım mı?
Burada byte dostum bile kullanmalı mıyım yoksa daha kolay mı/başka bir yol var mı?
Cevabınız için teşekkürler, bunun için de somut kullanım durumunu göstermek için benim sorumu düzenledim. Belki yanlış yaptığımı açıklamak için birkaç dakikanız var. – leozilla
Jikes. Kendi * javadoc * 'u okumalı. Aranacak kurucuyu belirtmeniz ve gerekiyorsa bağımsız değişkenler sağlamanız gerekir. Bu şekilde, Byte Buddy'nin tahmin etmesine gerek yok. Örnekler için 'MethodCallTest' bölümüne de bakabilirsiniz. –
Anlamıyorum. Bytebuddy sınıf yükleyicileri uygun değilse, varsayılan sınıf yükleyiciyi arama yeteneğine sahipsiniz. Bana öyle geliyor ki, sadece kendi sınıfını yazamayacağı, aynı paketi hedefleyen ve bu yöntemleri kullanarak yeni bir sınıf inşa etmek istediği ve sadece yeni sınıfını onlara çağırdığı için hiçbir sebep olmamalı. Sonra yeni sınıfında bir kurucu kurabilir ve her türlü eğlenceli şeyleri yapabilir. Bir kod değiştirmenin amacı, bir sınıfı değiştirmeniz gerektiğinde esneklik olmalıdır, ancak varsayılan java şeylerini yapamayacak kadar sınırlanmamalıdır. – Xype