在CDI之前,EJB 3還引入了依賴注入,但這有點基礎。 您可以將EJB(全狀態或無狀態)注入另一個EJB或Servlet(如果您的容器支持)。 當然,并不是每個應用程序都需要EJB的,這就是CDI如此受歡迎的原因。
首先,我已經舉了這個例子。 有一個Payment接口和2個實現。 現金付款和簽證付款。
我希望仍然可以使用相同的界面選擇我注入的女巫付款類型:
public interface Payment {void pay(BigDecimal amount);
}
這是兩個實現:
public class CashPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(CashPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} cash", amount.toString());}
}
public class VisaPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(VisaPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} with visa", amount.toString());}
}
要注入接口,我們使用@Inject批注。 注釋基本上按照它說的去做。 它注入一個組件,該組件在您的應用程序中可用。
@Inject private Payment payment;
當然,您看到的消息來自一英里遠,這是行不通的。 該容器具有我們的Payment接口的2個實現,因此他不知道要注入哪個。
類型[Payment]類型的依賴關系,在注入點[[field] @Inject private be.styledideas.blog.qualifier.web.PaymentBackingAction.payment]處帶有限定符[@Default]
因此,我們需要某種限定符來指出我們想要的實現。 CDI提供@Named批注,使您可以為實現命名。
@Named("cash")
public class CashPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(CashPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} cash", amount.toString());}
}
@Named("visa")
public class VisaPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(VisaPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} with visa", amount.toString());}
}
現在,當我們更改注入代碼時,我們可以指定所需的實現。
@Inject private @Named("visa") Payment payment;
這行得通,但是靈活性受到限制。 當我們想重命名@Named參數時,我們必須在使用它的每個地方都對其進行更改。 也沒有重構支持。
有一個更好的選擇,可以使用@Qualifier注釋使用定制注釋。 讓我們稍微更改一下代碼。
首先,我們創建新的注釋類型。
@java.lang.annotation.Documented
@java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
@javax.inject.Qualifier
public @interface CashPayment {
}
@java.lang.annotation.Documented
@java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
@javax.inject.Qualifier
public @interface VisaPayment {
}
添加到批注中的@Qualifier批注使此批注可由容器發現。 現在,我們可以簡單地將這些注釋添加到我們的實現中。
@CashPayment
public class CashPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(CashPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} cash", amount.toString());}
}
@VisaPayment
public class VisaPaymentImpl implements Payment {private static final Logger LOGGER = Logger.getLogger(VisaPaymentImpl.class.toString());@Overridepublic void pay(BigDecimal amount) {LOGGER.log(Level.INFO, "payed {0} with visa", amount.toString());}
}
現在我們唯一需要做的就是將我們的注入代碼更改為
@Inject private @VisaPayment Payment payment;
現在,當我們對限定符進行更改時,我們將獲得不錯的編譯器和重構支持。 這也為API或特定于域的語言設計增加了靈活性。
參考: Java EE6 CDI,來自Styled Ideas Blog的 JCG合作伙伴 Jelle Victoor的 命名組件和限定詞 。
- Java EE6裝飾器:在注入時裝飾類
- Java EE6事件:JMS的輕量級替代品
- Java EE中的配置管理
- 基本的EJB參考,注入和查找
- Java模塊化方法–模塊,模塊,模塊
- Java EE過去,現在和云7
- Java教程和Android教程列表
翻譯自: https://www.javacodegeeks.com/2011/10/java-ee6-cdi-named-components-and.html