HK2工厂实施单身人士

时间:2018-03-30 00:21:02

标签: jersey-2.0 hk2

我正在尝试了解Jersey应用程序中的HK2 Factory实现。

目标:如何实施单件工厂?

    // 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
  1. 当scope = Singleton

    • 创建两个MyFactory对象
    • 下一个请求失败,空指针异常@Inject。
  2. 当scope = RequestScoped,PerLookup

    • 每个请求都会创建两个MyFactory对象
  3. 通过Singleton工厂,我理解的是,工厂的一个对象(MyFactory)在注射时提供某种物体。

    所以(1)应该工作还是我错过了什么?

    为什么两个工厂对象?

    有什么建议吗?提前谢谢。

    HK2 Version : 2.5.0-b60
    Jersey Version: 2.26
    

    有关NPE的其他信息

    它不是来自HK2,但 .in(Singleton.class) .in(PerLookup.class)

    之间的行为不同
    // 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);
    

1 个答案:

答案 0 :(得分:2)

执行bindFactory时,使用第二个参数将工厂绑定为单例。你这样做只有提供方法绑定为单例。因此,要使工厂本身也成为单身人士,请执行以下操作:

bindFactory(MyFactory.class, Singleton.class).to(SomeObject.class).in(Singelton.class);

这应该得到提供的东西和工厂本身绑定为单身。