2016-06-08 60 views
0

我想用構造函數參數注入一個CDI託管bean的實例。我已經註釋一個構造函數參數與@注入,例如: -帶參數的CDI注入,哪裏是實例?

@Stateless 
public class ShoppingCart { 

    int capacity; 

    ShoppingCart(){}; 

    @Inject 
    ShoppingCart(int capacity) { 
    this.capacity = capacity; 
    } 
' 
' 
} 

我如何可以注入一個實例購物到另一個CDI託管bean,這樣我其實有我的購物比如我可以調用其他方法? 相當於: -

ShoppingCart sc = new ShoppingCart(10); 

所有的例子似乎剛剛訪問引用bean的屬性和不實際獲得bean本身,例如實例從3.7. Bean constructors

@SessionScoped 
public class ShoppingCart implements Serializable { 
    private User customer; 

    @Inject 
    public ShoppingCart(User customer) { 
     this.customer = customer; 
    } 

    public ShoppingCart(ShoppingCart original) { 
     this.customer = original.customer; 
    } 

    ShoppingCart() {} 

    ... 
} 

@ConversationScoped 
public class Order { 
    private Product product; 
    private User customer; 

    @Inject 
    public Order(@Selected Product product, User customer) { 
     this.product = product; 
     this.customer = customer; 
    } 

    public Order(Order original) { 
     this.product = original.product; 
     this.customer = original.customer; 
    } 

    Order() {} 

    ... 
} 

定單實例不以我的購物對象,它可以調用我的購物方法,最終,你最終會得到,如果你沒有

@Inject 
ShoppingCart cart; 

但當然,這就要求你使用setter方法在 容量值之後通過一個setter方法: -

cart.setCapacity = 10; 

似乎有一些懷疑我是否真的有可能@注入一個具有構造函數參數的bean?我還沒有找到一個例子,任何幫助總是感激。

+0

容量從哪裏來?它是配置嗎? –

回答

-1

你需要使用這種情況下的生產者方法。

首先,定義一個限定符對於這種類型的購物車的(購物車用10容量):

@Qualifier 
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface TenCapacity { 
} 

然後定義爲如何創建這種類型的購物車的生產方法:

public class ShoppingCart { 

    int capacity; 

    ShoppingCart() { 
    }; 

    public ShoppingCart(int capacity) { 
     this.capacity = capacity; 
    } 

    @Produces 
    @TenCapacity 
    public static ShoppingCart newTenCapacityShoppingCart() { 
     return new ShoppingCart(10); 
    } 
} 

然後使用預選賽

@Inject 
@TenCapacity 
private ShoppingCart shoppingCart; 
注入這種類型的購物車210

如果您需要注入許多具有不同容量的購物車,則可以考慮使用InjectionPoint來避免創建許多不同的限定符。請參閱this的想法。

-1

生產者可能是一種去這裏的方式。

首先,如果你只創建一個給定的幾類ShoppingCart,你可能希望創建與預選賽等一整套生產商:

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

和製作人給你這個基本的購物車看起來像這樣:

@Produces 
@Basic 
public ShoppingCart createBasicShoppingCart() { 
    return new ShoppingCart(10); //assuming 10 is desired "basic" value 
} 

但是,如果您希望在創建對象時控制容量,CDI不能直接幫助您。你需要創建一個邏輯來決定這個容量,並把這個邏輯放到生產者中。另外,根據CDI spec

生產者方法可以有任何數量的參數。所有生產者方法參數都是注射點。

因此,您可以自由地向該生產商注入,並使用其元數據來確定購物車的容量。

@Produces 
@Custom // assuming you created this qualifier 
public ShoppingCart createShoppingCart(Order order) { 
    int desiredCapacity; 
    // determine desired capacity 
    // you can use any data from injected parameters 
    // as well as data from bean declaring this producer 
    desiredCapacity = order.getAllProducts.size(); 
    return new ShoppingCart(desiredCapacity); 
} 
+0

非常感謝您(和@Ken Chan)的詳細解釋。 您是否可以驗證,因爲即使我們使用** new ShoppingCart **,我們正在使用\ @Produces註釋,注入的ShoppingCart由CDI管理,因此如果需要的話,仍然可以使用\ @Inject? – mikee

+0

@mikee我不知道我理解你的問題嗎? 你的意思是即使你有一個用'new'關鍵字創建bean的生產者,CDI仍然會管理這個bean嗎? 如果是這樣,答案是**是**。只要你用製作人創建它,CDI將管理它,你可以使用'@Inject'。 – Siliarus