2016-06-08 20 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