先貼一段代碼,下面都用到 java
import javax.enterprise.inject.Produces; @SessionScoped public class Preferences implements Serializable { private PaymentStrategyType paymentStrategy; ... @Produces @Preferred public PaymentStrategy getPaymentStrategy() { switch (paymentStrategy) { case CREDIT_CARD: return new CreditCardPaymentStrategy(); case CHECK: return new CheckPaymentStrategy(); case PAYPAL: return new PayPalPaymentStrategy(); default: return null; } } }
//注入一個Producer methods @Inject @Preferred PaymentStrategy paymentStrategy;
@Produces @Preferred @SessionScoped public PaymentStrategy getPaymentStrategy() { ... }注意:Producer methods不繼承聲明此Producer methods的Bean的Scope.
在Producer methods一開始的實例有一個潛在的問題
CreditCardPaymentStrategy 的實現使用 Java new 運算符來實例化。 spring
private PaymentStrategyType paymentStrategy;
而producer methods應該理解爲一個獨立的Bean,而paymentStrategy是從Preferences 中用new實例化的.因此咱們應該使用下面這種方式來使用producer methods方法. 安全
@Produces @Preferred @SessionScoped public PaymentStrategy getPaymentStrategy(CreditCardPaymentStrategy ccps, CheckPaymentStrategy cps, PayPalPaymentStrategy ppps) { switch (paymentStrategy) { case CREDIT_CARD: return ccps; case CHEQUE: return cps; case PAYPAL: return ppps; default: return null; } }
這裏會有問題,若是CreditCardPaymentStrategy 是一個@RequestScope,那這裏必然是要發生錯誤的.由於注入的CreditCardPaymentStrategy Bean實例是request,在@SessionScoped使用前容器就會進行銷燬.那麼就出錯了. 服務器
@Produces @Preferred @SessionScoped public PaymentStrategy getPaymentStrategy(@New CreditCardPaymentStrategy ccps, @New CheckPaymentStrategy cps, @New PayPalPaymentStrategy ppps) { switch (paymentStrategy) { case CREDIT_CARD: return ccps; case CHEQUE: return cps; case PAYPAL: return ppps; default: return null; } }
在CDI 1.1 @New限定符被棄用。CDI鼓勵應用程序注入@Dependent範圍bean。 async
@Produces @RequestScoped Connection connect(User user) { return createConnection(user.getId(), user.getPassword()); }而在一個相同的類中,disposer method能夠進行匹配.
void close(@Disposes Connection connection) { connection.close(); }說明:在同一個類中,disposer method能夠進行匹配類型爲Connection 的Procucer methods,從而在 Procucer methods週期結束後進行jdbc的連接關閉.
import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Disposes; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Resources { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @RequestScoped protected EntityManager createEntityManager() { return entityManagerFactory.createEntityManager(); } //參數必須對應上面方法的返回值 protected void closeEntityManager(@Disposes EntityManager entityManager) { if ( entityManager.isOpen() ) { entityManager.close(); } } }
結束. ide