HK2 工厂实现单例
HK2 Factory Implementation Singleton
我正在尝试了解 Jersey 应用程序中的 HK2 工厂实现。
目标:如何实现单例工厂?
// Below is the simple factory implementation
public class MyFactory implements Factory<SomeObject> {
private static final Logger logger = LoggerFactory.getLogger(MyFactory.class);
private final CloseableService closeService;
@Inject
public MyFactory(CloseableService closeService) {
this.closeService = closeService;
}
@Override
public MyFactory provide() {
logger.debug("provide object from MyFactory");
SomeObject objectFromFactory = new SomeObject();
this.closeService.add(() -> dispose(objectFromFactory));
return objectFromFactory;
}
@Override
public void dispose(SomeObject instance) {
// destroy instance
logger.debug("dispose object from MyFactory");
}
}
// and binding
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
// and injecting in some resource class
@Inject
SomeObject useThisObject;
//updated information
AbstractBinder abstractBinder = configureBinder();
ServiceLocator appServiceLocator = configureHK2(abstractBinder);
public static AbstractBinder configureBinder() {
return new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
}
}
public ServiceLocator configureHK2(AbstractBinder binder) {
ServiceLocatorFactory factory = ServiceLocatorFactory.getInstance();
ServiceLocator locator = factory.create("my-test-server");
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
DynamicConfiguration dc = dcs.createDynamicConfiguration();
locator.inject(binder);
binder.bind(dc);
dc.commit();
return locator;
}
启动应用程序时,我在日志中看到以下内容
10:38:34.122 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.MyFactory provide - object from MyFactory
10:38:35.700 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:37.743 [grizzly-http-server-0] DEBUG com.test.MyFactory - dispose object from MyFactory
当scope = Singleton时
- 创建 MyFactory 的两个对象
- 下一个请求因空指针异常 @Inject 而失败。
当scope = RequestScoped时,PerLookup
- 每个请求都会创建两个MyFactory对象
对于Singleton factory,我的理解是,工厂(MyFactory)的单个对象,它在注入时提供某种对象。
那么 (1) 应该有效还是我遗漏了什么?
为什么工厂有两个对象?
有什么建议吗?提前致谢。
HK2 Version : 2.5.0-b60
Jersey Version: 2.26
有关 NPE 的其他信息
它不是来自 HK2,但 .in(Singleton.class) 和 .in(PerLookup.class)[= 之间的行为不同62=]
// SomeObject looks like
Class SomeObject
{
private Stack<String> someStack;
public SomeObject() {
// this may be the issue for Singleton
this.someStack = new Stack();
}
public someOperation(String stackIt)
{
// NPE location
this.someStack.push(stackIt);
}
}
NPE 在下方时在上方位置
bindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(Singleton.class);
当低于
时,上方位置无NPE
bindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(PerLookup.class);
当您执行 bindFactory 时,使用第二个参数将 Factory 绑定为单例。你这样做的方式只有 provide 方法被绑定为一个单例。因此,要使工厂本身也成为单身人士,请这样做:
bindFactory(MyFactory.class, Singleton.class).to(SomeObject.class).in(Singelton.class);
这应该将所提供的东西和工厂本身绑定为单例。
我正在尝试了解 Jersey 应用程序中的 HK2 工厂实现。
目标:如何实现单例工厂?
// Below is the simple factory implementation
public class MyFactory implements Factory<SomeObject> {
private static final Logger logger = LoggerFactory.getLogger(MyFactory.class);
private final CloseableService closeService;
@Inject
public MyFactory(CloseableService closeService) {
this.closeService = closeService;
}
@Override
public MyFactory provide() {
logger.debug("provide object from MyFactory");
SomeObject objectFromFactory = new SomeObject();
this.closeService.add(() -> dispose(objectFromFactory));
return objectFromFactory;
}
@Override
public void dispose(SomeObject instance) {
// destroy instance
logger.debug("dispose object from MyFactory");
}
}
// and binding
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
// and injecting in some resource class
@Inject
SomeObject useThisObject;
//updated information
AbstractBinder abstractBinder = configureBinder();
ServiceLocator appServiceLocator = configureHK2(abstractBinder);
public static AbstractBinder configureBinder() {
return new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
}
}
public ServiceLocator configureHK2(AbstractBinder binder) {
ServiceLocatorFactory factory = ServiceLocatorFactory.getInstance();
ServiceLocator locator = factory.create("my-test-server");
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
DynamicConfiguration dc = dcs.createDynamicConfiguration();
locator.inject(binder);
binder.bind(dc);
dc.commit();
return locator;
}
启动应用程序时,我在日志中看到以下内容
10:38:34.122 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.MyFactory provide - object from MyFactory
10:38:35.700 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:37.743 [grizzly-http-server-0] DEBUG com.test.MyFactory - dispose object from MyFactory
当scope = Singleton时
- 创建 MyFactory 的两个对象
- 下一个请求因空指针异常 @Inject 而失败。
当scope = RequestScoped时,PerLookup
- 每个请求都会创建两个MyFactory对象
对于Singleton factory,我的理解是,工厂(MyFactory)的单个对象,它在注入时提供某种对象。
那么 (1) 应该有效还是我遗漏了什么?
为什么工厂有两个对象?
有什么建议吗?提前致谢。
HK2 Version : 2.5.0-b60
Jersey Version: 2.26
有关 NPE 的其他信息
它不是来自 HK2,但 .in(Singleton.class) 和 .in(PerLookup.class)[= 之间的行为不同62=]
// SomeObject looks like
Class SomeObject
{
private Stack<String> someStack;
public SomeObject() {
// this may be the issue for Singleton
this.someStack = new Stack();
}
public someOperation(String stackIt)
{
// NPE location
this.someStack.push(stackIt);
}
}
NPE 在下方时在上方位置
bindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(Singleton.class);
当低于
时,上方位置无NPEbindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(PerLookup.class);
当您执行 bindFactory 时,使用第二个参数将 Factory 绑定为单例。你这样做的方式只有 provide 方法被绑定为一个单例。因此,要使工厂本身也成为单身人士,请这样做:
bindFactory(MyFactory.class, Singleton.class).to(SomeObject.class).in(Singelton.class);
这应该将所提供的东西和工厂本身绑定为单例。