How do I make a HK2 ServiceLocator use the Singleton service instances from the ServiceLocator that it's bridged from?

泪湿孤枕 提交于 2019-12-01 00:26:32

There was a bug in the ServiceLocator bridge which has been fixed. The fix will be in hk2 2.5.0-b07 or later!

In the meantime (and in case it is indeed designed behaviour) I have achieved a workaround by implementing my own InjectionResolver. It's not a complete solution as it only works for injection (i.e. a call to ServiceLocator.getService() will not bridge) but it does what I need for now.

Here is the class if anyone needs it. Instead of calling ExtrasUtilities.bridgeServiceLocator(_innerServiceLocator, _outerServiceLocator); you call BridgingInjectionResolver.bridgeInjection(_innerServiceLocator, _outerServiceLocator);

@Singleton
@Rank(1)
public class BridgingInjectionResolver implements InjectionResolver<Inject>
{
  @Inject
  private ServiceLocator _localServiceLocator;

  private ServiceLocator _remoteServiceLocator;

  public BridgingInjectionResolver()
  {
  }

  /**
   * This method will bridge injection of all non-local services from the from ServiceLocator into the into
   * ServiceLocator.  The two ServiceLocators involved must not have a parent/child relationship
   *
   * @param into The non-null ServiceLocator that will be able to inject services from the from ServiceLocator
   * @param from The non-null ServiceLocator that will provide services for injection to the into ServiceLocator
   */
  public static void bridgeInjection(ServiceLocator into, ServiceLocator from)
  {
    checkParentage(into, from);
    checkParentage(from, into);
    ServiceLocatorUtilities.addClasses(into, BridgingInjectionResolver.class);
    into.getService(BridgingInjectionResolver.class).setRemoteServiceLocator(from);
  }

  private static void checkParentage(ServiceLocator a, ServiceLocator b)
  {
    ServiceLocator originalA = a;

    while (a != null) {
      if (a.getLocatorId() == b.getLocatorId()) {
        throw new IllegalStateException("Locator " + originalA + " is a child of or is the same as locator " + b);
      }

      a = a.getParent();
    }
  }

  @Override
  public Object resolve(Injectee injectee, ServiceHandle<?> root)
  {
    ActiveDescriptor<?> ad = _localServiceLocator.getInjecteeDescriptor(injectee);
    if (ad != null) {
      return _localServiceLocator.getService(ad, root, injectee);
    }
    ad = _remoteServiceLocator.getInjecteeDescriptor(injectee);
    if ((ad != null) && (ad.getDescriptorVisibility() == DescriptorVisibility.LOCAL)) {
      ad = null;
    }
    if (ad == null) {
      if (injectee.isOptional()) {
        return null;
      }

      throw new MultiException(new UnsatisfiedDependencyException(injectee));
    }
    return _remoteServiceLocator.getService(ad, root, injectee);
  }

  @Override
  public boolean isConstructorParameterIndicator()
  {
    return false;
  }

  @Override
  public boolean isMethodParameterIndicator()
  {
    return false;
  }

  private void setRemoteServiceLocator(ServiceLocator remoteServiceLocator)
  {
    _remoteServiceLocator = remoteServiceLocator;
  }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!