2011-09-22 40 views
0

編輯: 也許更簡潔的方式來問這個問題是:難道春天提供一個辦法,我提供我自己的聽衆/工廠/決策解決在注射時間曖昧候選人邏輯?春 - 由指定的環境資格注射候選人


事實上,可以說下面的成員字段的@Environmental預選賽是不必要的:如果@進樣離子是模糊......讓我幫忙嗎?事實上,@ResolveWith(EnvironmentalResolver.class)將是好的太..


春嘗試注入的依賴(使用說明),我知道我需要的,如果我對@Qualifier的@Inject點有多個實現該接口的組件。

我希望做的是這樣的:

class MyFoo implements Foo { 
    @Inject 
    @Environmental 
    private Bar bar; 
} 

@Environmental(Environment.Production) 
class ProductionBar implements Bar { 
} 

@Environmental({Environment.Dev, Environment.Test}) 
class DevAndTestBar implements Bar { 
} 

我預計我需要建立某種不確定性求解的這看起來會(依稀)是這樣的:

class EnvironmentalBeanAmbiguityResolver { 

    // set from configuration, read as a system environment variable, etc. 
    private Environment currentEnvironment; 

    public boolean canResolve(Object beanDefinition) { 
     // true if definition has the @Environmental annotation on it 
    } 

    public Object resolve(Collection<Object> beans) { 
     for (Object bean : beans) { 
      // return bean if bean @Environmental.values[] contains currentEnvironment 
     } 
     throw new RuntimeException(...); 
    } 
} 

在這方面有用的一個例子是我們有一個與最終用戶聯繫的服務。現在我只是在AOP方面有一個黑客攻擊方法,在方法調用「MailSender」之前,檢查一個「Production」環境標誌,如果沒有設置,它將發送郵件給我們而不是用戶郵件。而不是將其包裝在特定於郵件發送的AOP方面,而是能夠根據當前環境區分服務。有時,這只是「生產」或「不生產」的問題,正如我上面演示的那樣,但每個環境的定義也可以。

我認爲這是可以重複使用的區域太...如@Regional和@Regional(Region.UnitedStates)等等等等。

我會想象一下,如果你想直接依賴某些環境,@Environmental實際上就是一個@Qualifier你可能(一個@Environmental(Production)bean可能直接依賴@Environmental(Production)合作者 - 所以對於較低級別的項目不會含糊不清 - 同樣的@Regional(US)項目將取決於其他@Regional(US) )的項目expiclitly,並會繞過我的尚未理解BeanAmbiguityResolver)

謝謝。

回答

0

我想我解決了這個問題!

考慮以下幾點:

​​

現在,如果我有一個接口MyInterface的兩個類,實現它MyFooInterface和MyBarInterface這樣的:

public interface MyInterface { 
    public String getMessage(); 
} 

@Named 
@Environmental({ Environment.Testing, Environment.Production }) 
public class MyTestProdInterface implements MyInterface { 
    @Override 
    public String getMessage() { 
     return "I don't always test my code, but when I do, I do it in production!"; 
    } 
} 

@Named 
@Environmental(Environment.Development) 
public class DevelopmentMyInterface implements MyInterface { 
    @Override 
    public String getMessage() { 
     return "Developers, developers, developers, developers!"; 
    } 
} 

如果我想@Inject MyInterface的我會得到與人們預期的相同的多個bean定義錯誤。但是我可以添加@Ambiguous(EnvironmentalAmbiguity.class),然後EnvironmentalAmbiguity會告訴它滿足哪個bean定義。

另一種方法是使用一個List並通過它們全部看看它們是否滿足給定的bean定義,這將意味着依賴性不需要@Ambiguous註解。這可能更「IoC-ish」,但我也認爲它可能表現不佳。我沒有測試過。