public class DefaultPaymentProcessor implements PaymentProcessor { ... }
但在咱們的環境中,咱們不想使用這個默認的實現,因此咱們重寫了PaymentProcessor: java
@Alternative public class StagingPaymentProcessor implements PaymentProcessor { ... }
或者 app
@Alternative public class StagingPaymentProcessor extends DefaultPaymentProcessor { ... }
在bean.xml中進行配置 學習
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee"> <alternatives> <class>org.credo.StagingPaymentProcessor</class> </alternatives> </beans>
這樣就在項目啓動的時候使用了指定的實現. 測試
但不可能一個個的在bean.xml中配置.CDI提供了更方便的方法.以下@Alternative @Stereotype @Retention(RUNTIME) @Target(TYPE) public @interface Staging {}
在咱們這個環境要使用的Bean實現上加@Staging Stereotype註解. spa
@Staging public class StagingPaymentProcessor implements PaymentProcessor { ... }
最後咱們在bean.xml中僅需如此配置 .net
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"> <alternatives> <stereotype>org.mycompany.myapp.Staging</stereotype> </alternatives> </beans>
如今無論有多少Staging環境下使用的替換Bean,他們都將所有啓動. code
@Inject @LargeTransaction PaymentProcessor paymentProcessor;
因此咱們在系統中尚未徹底取代該默認實現,一個alternatives Bean在全部注射點能夠徹底重寫默認bean的惟一方法是alternatives Bean實現全部bean類型,全部限定符。好比上面PaymentProcessor 的alternatives Bean也加入了@LargeTransaction註解. xml
可是,若是默認的Bean申明瞭一個producer方法或者一個觀察者方法(cdi event 事件),那麼即時是如上述所說的那樣作,也仍是不夠的.咱們須要進行額外的一些處理.CDI提供了一個特殊的功能,叫作specialization(專業化),能夠幫助開發者避免這些陷阱。specialization是通知系統的方式來徹底替代和禁用一個bean的實現。 繼承
針對第二節的問題,使用@Specializes來處理,以下所示: 接口
@Alternative @Specializes public class MockCreditCardPaymentProcessor extends CreditCardPaymentProcessor { ... }
當啓用了這個Alternative Bean,即時其餘的Bean,包括默認的Bean,申明瞭Producer方法和觀察者方法,依然使用這個Alternative Bean.