2017-04-22 143 views
1

中調用的無參數構造函數,我想知道構造函數注入如何與需要一個bean類需要一個無參數構造函數的需求結合起來。在下面描述的測試之後,我的結論是,無參數構造函數被調用兩次,然後調用注入的構造函數。任何人都能解釋我爲什麼?什麼時候注入構造函數,什麼時候是CDI

爲了測試這種行爲我創建了一個HelloProducer類:

public class HelloProducer { 

    @Produces 
    @Hello 
    public String helloWildFly() { 
     return "Hello!"; 
    } 

} 

Hello預選賽:

@Qualifier 
@Retention(RUNTIME) 
@Target({METHOD, FIELD, PARAMETER, TYPE}) 
public @interface Hello { 
} 

然後,我創建了一個使用此生產者作爲注入的構造的bean類:

@Stateless 
public class HelloBean { 

    private final Logger log = LoggerFactory.getLogger("HelloBean"); 
    private String hello; 

    public HelloBean() { 
     log.warn("No-args constructor called"); 
     this.hello = "Hi!"; 
    } 

    @Inject 
    public HelloBean(@Hello String hello) { 
     log.warn("Injected constructor called"); 
     this.hello = hello; 
    } 

    public String getHello() { 
     return hello; 
    } 

} 

那麼,當我調用getHello()方法?你好!或嗨!?讓我們測試:

@RunWith(Arquillian.class) 
public class HelloBeanIT { 

    @Deployment 
    public static JavaArchive createDeployment() { 
     return ShrinkWrap.create(JavaArchive.class, "test.jar") 
       .addClass(HelloProducer.class) 
       .addClass(Hello.class) 
       .addClass(HelloBean.class) 
       .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); 
    } 

    @Inject 
    HelloBean helloBean; 

    @Test 
    public void testSomeMethod() { 
     assertThat(helloBean.getHello(), is("Hello!")); 
    } 

} 

那麼,該測試運行良好,所以被調用的最終構造函數是注入構造函數。但是,如果我看我看到日誌如下:

WARN [HelloBean] No-args constructor called 
WARN [HelloBean] No-args constructor called 
WARN [HelloBean] Injected constructor called 

那麼,爲什麼是注入的構造函數之前通過CDI叫了兩聲無參數的構造函數?

+0

注:當我刪除注入的構造的'HelloBean'測試方法返回嗨!並且無參數構造函數被調用三次。 –

回答

2

所以,通過一點挖掘,我發現了那裏實際發生的事情。

no-args構造函數調用在代理初始化期間發生,而帶參數的唯一調用是實際的對象創建(以及最終得到的結果)。爲了進一步闡述,你的bean是@Stateless--這意味着它是EJB和CDI bean(EJB的定義和CDI自動爲你選擇)。這兩個規範的操作方式都是在實際的實例之上創建一個代理對象,然後您只是傳遞代理引用而不是實際的實例。

因此,它是這樣的:

WARN [HelloBean] No-args constructor called -> CDI Proxy on top of EJB proxy 
WARN [HelloBean] No-args constructor called -> EJB proxy 
WARN [HelloBean] Injected constructor called -> actual instance creation 
+0

有道理!感謝您的解釋。 –

相關問題