注入不适用于嵌套对象[Jersey 2.22.1]

时间:2016-01-04 20:18:57

标签: java dependency-injection jersey inject hk2

我有一个带有外观对象的Jersey资源。这是在我的ResourceConfig中配置的,门面注入正常。 Facade包含一个DAO类,它也应该被注入并在同一个ResourceConfig中配置。现在我的问题; DAO类为null。因此,不注射。

@ApplicationPath("/service")
public class SystemSetup extends ResourceConfig {

public SystemSetup() {
    packages(false, "com.foo.bar");
    packages("org.glassfish.jersey.jackson");
    register(JacksonFeature.class);

    final LockManager manager = getLockManager();
    final SessionFactory sessionFactory = getSessionFactory();
    register(new AbstractBinder() {
        @Override
        protected void configure() {
            bindFactory(InjectFactory.getDaoFactory(sessionFactory)).to(Dao.class).in(Singleton.class);
            bindFactory(InjectFactory.getFacadeFactory(manager)).to(Facade.class).in(Singleton.class);
        }
    });
}
 @Path("/")
 @Produces("text/json")
 public class ViewResource {

    @Inject
    private Facade logic;
public class Facade {

    @Inject
    private Dao dao; //Not injected

工厂实例相当简单。他们只需调用构造函数并将参数传递给它。

奇怪的是,当我使用bind(Class对象)而不是bindFactory时,这绝对没问题。

修改

工厂

class InjectFactory {

    static Factory<Dao> getDaoFactory() {
        return new Factory<Dao>() {
            @Override
            public Dao provide() {
                return new Dao(new Object());
            }

            @Override
            public void dispose(Dao dao) {}
        };
    }

    static Factory<Facade> getFacadeFactory() {
        return new Factory<Facade>() {

            @Override
            public Facade provide() {
                return new Facade();
            }

            @Override
            public void dispose(Facade facade) {}
        };
    }
}

1 个答案:

答案 0 :(得分:0)

与大多数Di框架的情况一样,当您自己开始实例化时,通常会出现这样的情况:您正在将框架踢出方程式。这适用于Factory实例以及工厂创建的对象。所以Facade实例永远不会被框架触及,除非将它注入资源类。

您可以暂停ServiceLocator,并自行明确注入对象,如果您想自己创建它们。这里有几个选项。

1)将ServiceLocator注入Factory实例,然后注入Facade实例。

static Factory<Facade> getFacadeFactory() {
    return new Factory<Facade>() {

        @Context
        ServiceLocator locator;

        @Override
        public Facade provide() {
            Facade facade = new Facade();
            locator.inject(facade);
            return facade;
        }

        @Override
        public void dispose(Facade facade) {}
    };
}

@Inject
public SystemSetup(ServiceLocator locator) {
    packages("foo.bar.rest");
    packages("org.glassfish.jersey.jackson");
    register(JacksonFeature.class);

    register(new AbstractBinder() {
        @Override
        protected void configure() {
            bindFactory(InjectFactory.getDaoFactory()).to(Dao.class);

            Factory<Facade> factory = InjectFactory.getFacadeFactory();
            locator.inject(factory);
            bindFactory(factory).to(Facade.class);
        }
    });
}

2)或绑定Factory ,让框架注入ServiceLocator

public static class FacadeFactory implements Factory<Facade> {

    @Context
    ServiceLocator locator;

    @Override
    public Facade provide() {
        Facade facade = new Facade();
        locator.inject(facade);
        return facade;
    }

    @Override
    public void dispose(Facade facade) {}
}

register(new AbstractBinder() {
    @Override
    protected void configure() {
        bindFactory(InjectFactory.getDaoFactory()).to(Dao.class);
        bindFactory(InjectFactory.FacadeFactory.class).to(Facade.class);
    }
});