我的代码库中有以下情形:
//this bean, which will be injected,
//is not annotated
public class HelperUtil {
//only default constructor with no args
public void doThis(String _in) {
//...
}
public void doThat() {
//...
}
}
在下面的类中,我们进行注入(inject):
@Named
@Stateless
public class BusinessManager {
@PersistenceContext(unitName = "default")
private EntityManager em;
@Inject
private HelperUtil helperUtil ;
//...
}
问题1:什么时候将通过调用默认构造函数实际初始化将要注入(inject)的
HelperUtil
实例?当启动应用服务器(在我的情况下为BusinessManager
)时实例化了将其注入(inject)的第一个客户端(例如JBoss
)时,该操作完成了吗(该容器将被初始化,因为它被标注为@Stateless
)?问题2:在上述展览中,只要容器之外的其他客户端都没有直接通过调用构造函数而不是通过
HelperUtil
获取实例来请求实例,那么singleton
仍将是DI
吗?问题3:与直接调用构造函数(
@Inject
)相比,在这种情况下使用DI和HelperUtil helper = new HelperUtil();
有什么优势? 最佳答案
这取决于,但是您可以控制这些事件以执行一些代码,例如:
如果您需要在应用启动时执行bean,则需要向bean添加@Startup
批注。
如果您需要在不访问其他注入(inject)资源的情况下初始化bean,则可以使用常规构造函数。
如果在初始化Bean时需要执行某些方法,请在该方法中使用@PostConstruct
批注。
您需要记住,创建取决于bean的范围,在这种情况下,它是无状态bean,如果某些客户端注入(inject)了bean,并且没有其他可用实例,则将创建bean,如果为singleton,那么将创建bean。仅一次,通常将在需要它们时创建该bean(一个单例bean初始化,直到第一个客户端使用它,或者在使用注释启动时)
编辑:
对于第三个问题,好处是,如果您在HelperUtil
中使用资源或其他bean,它们将使用适当的值进行初始化,例如,如果您使用实体管理器或帮助程序中的其他bean。如果您的助手只处理静态方法或其他简单实用程序之类的东西,那么您是对的,好处是没有,您可以像静态助手类一样简单地进行管理,但是如果您需要EE资源,则需要按顺序管理bean获取所有注入(inject)和资源
编辑2:
经过几年的编程并在Java和C#Core中使用依赖注入(inject),我可以添加:问题3非常开放,使用DI将使您的代码能够:
new ObjectModified(oldParams)
以添加新参数当存在这种依赖关系时,您可以开始修改,然后修改使用它的类,依此类推……直到您发现自己像以前一样修改了相同的类!,因此您开始一个循环,因为两者之间的通信路径您的对象很复杂。
当您使用DI时,可以早日检测到这种周期,因此您可以重新考虑您的体系结构,以避免这种生产力的黑洞
DI是使大型项目保持可维护性的非常强大的工具,现在已经存在于许多环境和框架中,因为它非常有用,如果仍然不能说服您,则可以尝试在Spring boot,PlayFramework,Net Core, Java EE,Ruby on Rails ....和许多其他已将其包含在内的标准流程,并构建了中等大小的应用程序,然后尝试不使用DI