2017-09-25 77 views
2

我有一個項目使用Jersey 2.25(與HK2 2.5-b30)。最初,我使用的是HK2-Guice Bridge。但是,對於某些情況,這似乎意外失敗(尤其是在Guice配置的自定義註釋中註釋了字符串的情況下,Guice執行注入時會正常工作,但在HK2執行時會默默失敗)。因爲同一個對象根據注入方式的不同可能會有所不同,所以我很害怕將它們結合使用。如何讓HK2像Guice一樣注入未明確配置的類?

我現在正在切換所有使用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沒有任何問題實例化。

回答

2

您還可以使用貪婪的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; 
    } 

} 

使用上述解析器的時候,因爲它會添加東西到你的服務定位器,你可能沒有指望你應該小心。它也可能不適合注入像Strings或其他類型的東西。不過,可能適合你的用例。

如果您的注射點正在注入一個接口,將無法正常工作!

+0

是的;這看起來像我需要的東西。我會添加一些檢查,以確保我實際上正在注入我想要注入的東西。我認爲這正是吉斯橋所使用的,但至少這樣做明確地提供了更多的可見性和控制力。 –

1

a few extra steps you need配置HK2自動填入您的服務:

  1. 確保您已標註了@Contract的接口和你的實現與@Service
  2. 您需要在構建過程中運行HK2 Metadata Generator 。這會生成HK2在運行時需要的服務文件,以確定哪些類可以實現哪些合約接口。
  3. 使用ServiceLocatorUtilities.createAndPopulateServiceLocator()檢索ServiceLocator實例。

請注意,具體細節或如何爲您工作取決於您正在使用什麼樣的框架(如球衣)。見Using HK2 with Jersey