【问题标题】:Dropwizard HK2 injectionDropwizard HK2 注射液
【发布时间】:2018-07-17 16:01:56
【问题描述】:

我在使用 dropwizard 方面是个新手。目前我正在尝试实现 HK2 依赖注入。这在资源内部工作得很好,但在资源外部不起作用。这是我正在做的事情:

Client client = new JerseyClientBuilder(environment).using(configuration.getJerseyClientConfiguration()).build("contentmoduleservice");

    //DAOs
    ContentModuleDAO contentModuleDAO = new ContentModuleDAO(hibernate.getSessionFactory());
    ModuleServedDAO moduleServedDAO = new ModuleServedDAO(hibernate.getSessionFactory());

    //Manager
    ContentModuleManager moduleManager = new ContentModuleManager();
    EntityTagManager eTagManager = new EntityTagManager();
    ProposalManager proposalManager = new ProposalManager(client, configuration);

    environment.jersey().register(new AbstractBinder() {
        @Override
        protected void configure() {
            bind(eTagManager).to(EntityTagManager.class);
            bind(contentModuleDAO).to(ContentModuleDAO.class);
            bind(moduleServedDAO).to(ModuleServedDAO.class);
            bind(proposalManager).to(ProposalManager.class);
            bind(moduleManager).to(ContentModuleManager.class);
        }
    });

我创建了我想要注入的类的实例并绑定它们。

在我的资源中注入工作:

@Api
@Path("/api/contentmodule")
public class ContentModuleResource {

    static final Logger LOG = LoggerFactory.getLogger(ContentModuleResource.class);
    static final int MAX_PROPOSALS_PER_MODULE = 10;

    @Inject
    private ContentModuleDAO contentModuleDAO;

    @Inject
    private EntityTagManager eTagManager;

    @Inject
    private ProposalManager proposalManager;

    @Inject
    private ContentModuleManager contentModuleManager;

所有这些变量都填充了正确类的实例。

问题是:ContentModuleManager 也应该通过注入获取其中一些类:

public class ContentModuleManager {

@Inject
private ContentModuleDAO contentModuleDAO;

@Inject
private ProposalManager proposalManager;

@Inject
private ModuleServedDAO moduleServedDAO;

但那些都是空的。有人可以解释一下为什么会发生这种情况以及我该如何解决这个问题吗? :D

谢谢!

【问题讨论】:

    标签: java dependency-injection jersey dropwizard hk2


    【解决方案1】:

    如果您要自己实例化服务,那么它不会经历 DI 生命周期并且永远不会被注入。如果您只是将服务注册为类,则可以让容器创建服务

    bind(ContentModuleManager.class)
        .to(ContentModuleManager.class)
        .in(Singleton.class);
    

    另一方面,如果您自己创建所有服务并且所有服务都可用,那么您为什么不根本不使用 DI 容器呢?只需通过构造函数传递所有服务。无论您是使用构造函数注入1 还是手动传递构造函数,通过构造函数获取服务无论如何都是很好的做法,因为它可以更轻松地测试服务。


    1 - 构造函数注入

    private Service service;
    
    @Inject
    public OtherService(Service service) {
       this.service = service;
    }
    

    【讨论】:

    • 感谢您的回答 :) 如果我像您解释的那样将它们注册为一个类,我会收到 UnsatisfiedDependencyException:“SystemInjecteeImpl 没有可用于注入的对象(r​​equiredType=ContentModuleDAO,parent=ContentModuleResource, . ..”。你知道为什么会这样吗?关于构造函数注入:如何创建使用构造函数注入的类的新实例?将其他服务直接传递给构造函数绝对是一种方法。我只是想通过注入尝试:)
    • 好的,发现错误了。其中一些类的构造函数没有依赖注入。现在它就像魅力一样!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多