2015-07-07 34 views
6

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ı?

cevap

3

herhangi bayt kodu olmadan bir kurucusu tanımlamak mümkün değil. Bu, Java'da yasadışı olan soyut bir kurucu olacaktır. Gelecek sürüm için javadoc'a daha kesin bir açıklama ekleyeceğim. Bunu dikkatime sunduğun için teşekkürler. Burada Byte Buddy kullanmalıdır türlü hava şartlarına gelince

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

:

herhangi yapıcısı için gerekli olan bir süper yöntem çağrısı tanımlamanız gerekir gördüğümü küçük kodundan söyleyemem. Sormanız gereken soru: Hem kodun miktarını hem de onu takip etmenin karmaşıklığını göz önüne alarak kodumu kolaylaştırır mı? Byte Buddy kodunuzun kullanımını kolaylaştırırsa (ve çalıştırmak için), kullanın. Değilse, kullanma.

+0

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

+0

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. –

+0

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