我们正在使用通过ExtrasUtilities.bridgeServiceLocator()
将应用 ServiceLocator 桥接到 Jersey ServiceLocator 来将在一个 ServiceLocator 中创建的现有 Singleton 应用程序服务注入到 Jersey RESTful Web 服务中。
然而,存在于“外部”定位器中的单例并没有被使用——当注入到 Jersey 服务中时,每个服务都被再次创建。似乎 Singleton 仅在 ServiceLocator 范围内可见,即使它是桥接的。
这是预期的行为吗?如果是这样,有什么方法可以改变这种行为并在桥接的 ServiceLocators 上拥有一个真正的单例?
我已将问题提取到一组测试类中,这些类说明了以下几点:
public class BridgedServiceTest
{
private ServiceLocator _outerServiceLocator;
private ServiceLocator _innerServiceLocator;
@Test
public void testBridgedInnerServiceOK() throws Exception
{
ServiceLocatorFactory serviceLocatorFactory = ServiceLocatorFactory.getInstance();
_outerServiceLocator = serviceLocatorFactory.create("Outer");
ServiceLocatorUtilities.addClasses(_outerServiceLocator, SingletonServiceImpl.class);
_innerServiceLocator = serviceLocatorFactory.create("Inner");
ExtrasUtilities.bridgeServiceLocator(_innerServiceLocator, _outerServiceLocator);
final Client client1 = new Client();
_outerServiceLocator.inject(client1);
assertThat(SingletonServiceImpl.instanceCount.get(), Matchers.is(1));
client1.test();
final Client client2 = new Client();
_innerServiceLocator.inject(client2);
// next line fails as instance count is 2
assertThat(SingletonServiceImpl.instanceCount.get(), Matchers.is(1));
client2.test();
}
@After
public void tearDown() throws Exception
{
_innerServiceLocator.shutdown();
_outerServiceLocator.shutdown();
}
}
@Contract
public interface SingletonService
{
void fulfil();
}
@Service
public class SingletonServiceImpl implements SingletonService
{
public static AtomicInteger instanceCount = new AtomicInteger();
@PostConstruct
public void postConstruct()
{
instanceCount.incrementAndGet();
}
@Override
public void fulfil()
{
System.out.println("Contract Fulfilled.");
}
}
public class Client
{
@Inject
private SingletonService _singletonService;
public void test()
{
_singletonService.fulfil();
}
public SingletonService getSingletonService()
{
return _singletonService;
}
}