簡體   English   中英

我如何使HK2像Guice一樣注入未明確配置的類?

[英]How do I make HK2 act like Guice for injecting classes that weren't configured explicitly?

我有一個使用Jersey 2.25的項目(使用HK2 2.5-b30 )。 最初,我使用HK2-Guice Bridge 但是,這似乎在某些情況下會意外失敗(特別是,在Guice進行注入時,使用在Guice中配置的自定義批注對字符串進行批注的情況會很好,但在HK2進行注入時會默默失敗)。 由於同一個對象根據注入方式的不同會有所不同,因此對同時使用這兩個對象感到非常恐懼。

我現在將所有內容都切換為使用HK2,但可悲的是,在某些情況下HK2會失敗,而Guice會成功。 特別是,HK2似乎不喜歡在未顯式配置類型的地方進行注入。 Guice很高興能夠創建這些類的新實例並進行遞歸注入,但HK2並沒有那么多。 例如,

1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=TimeRangeRequestValidator,parent=GetWatchlistEventsImpl,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1218743359)

如您所見,錯誤消息根本不是很有幫助。 它應該能夠創建一個TimeRangeRequestValidator ,它引用一些其他對象,Guice可以毫無問題地創建所有這些對象。 在HK2和Guice之間是否有一些不同的行為列表,所以我可以找出為什么它不起作用?

注意, TimeRangeRequestValidator是一個用@Singleton注釋的類(不是接口),它具有默認的公共構造函數和一個用Inject注釋的字段。 Guice實例化它沒有問題。

您還可以使用貪婪的JustInTimeResolver 我在下面寫了一篇:

@Singleton
@Visibility(DescriptorVisibility.LOCAL)
public class GreedyResolver implements JustInTimeInjectionResolver {
    private final ServiceLocator locator;

    @Inject
    private GreedyResolver(ServiceLocator locator) {
        this.locator = locator;
    }

    @Override
    public boolean justInTimeResolution(Injectee failedInjectionPoint) {
        Type type = failedInjectionPoint.getRequiredType();
        if (type == null) return false;

        Class<?> clazzToAdd = null;
        if (type instanceof Class) {
            clazzToAdd = (Class<?>) type;
        }
        else if (type instanceof ParameterizedType) {
            Type rawType = ((ParameterizedType) type).getRawType();
            if (rawType instanceof Class) {
                clazzToAdd = (Class<?>) rawType;
            }
        }

        if (clazzToAdd == null) return false;
        if (clazzToAdd.isInterface()) return false;

        ServiceLocatorUtilities.addClasses(locator, clazzToAdd);
        return true;
    }

}

使用上面的解析器時,請務必小心,因為它會將您可能沒有想到的東西添加到ServiceLocator中。 在注入諸如Strings之類的東西或其他類型的東西時,它也可能做得不好。 不過,可能適用於您的用例。

如果您的注入點正在注入接口,則將不起作用!

您需要一些額外的步驟來配置HK2以自動填充服務:

  1. 確保已使用@Contract注釋了接口,並已使用@Service注釋了實現
  2. 您需要在構建期間運行HK2元數據生成器 這將生成HK2在運行時需要的服務文件,以確定哪些類實現了哪些協定接口。
  3. 使用ServiceLocatorUtilities.createAndPopulateServiceLocator()檢索ServiceLocator實例。

請注意,具體細節或其對您的工作方式取決於您所使用的框架(例如球衣)。 請參閱將HK2與Jersey一起使用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM