什么时候注入bean实际初始化?

amp*_*ent 5 java jboss dependency-injection cdi

我的代码库中有以下场景:

//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() {
      //...
   }
}
Run Code Online (Sandbox Code Playgroud)

在下面的课程中我们进行注射:

@Named
@Stateless
public class BusinessManager {

    @PersistenceContext(unitName = "default")
    private EntityManager em;

    @Inject
    private HelperUtil helperUtil ;

    //...
}
Run Code Online (Sandbox Code Playgroud)

Q1: 何时HelperUtil通过调用默认构造函数实际初始化实例?当注入它的第一个客户端(例如BusinessManager)在应用服务器(在我的情况下JBoss)启动时被实例化(并且由于它被注释为将由容器初始化),它是否已完成@Stateless

Q2: 在上面的展览中,只要没有客户端以外的客户端通过直接调用构造函数而不是通过?获取实例来请求实例,它将HelperUtil保持不变?singletonDI

问题3: 使用DI的优势是什么?@Inject在这种情况下直接调用构造函数(HelperUtil helper = new HelperUtil();)?

rek*_*m87 6

这取决于,但您可以控制这些事件来执行某些代码,例如:如果您需要在应用程序启动时执行bean,则需要向@Startupbean 添加注释.如果需要初始化bean而无需访问其他注入资源,则可以使用普通构造函数.如果在初始化bean时需要执行某些方法,请使用@PostConstruct方法中的注释.

你需要记住的是,创建依赖于bean的范围,你的情况下,这是一个无状态的bean,如果某些客户端注入它的bean将被创建并有没有其他可用的情况下,如果是单身,然后将豆腐创建只需一次,一般来说,bean将在需要时创建(单例bean初始化直到第一个客户端使用它,或者在启动时使用注释)

编辑: 对于第三个问题,其优点是,如果你使用的资源,或其他豆你里面HelperUtil,他们将用正确的价值观,如果您使用的实体管理器,或其他豆类你的助手里面初始化,例如.如果您的助手将处理像静态方法或其他简单的实用程序,那么你是对刚刚的事情,其优点是没有,你可以简单地管理像一个静态辅助类,但是如果你需要EE资源,你需要的豆,以管理获取所有注入和资源

编辑2: 经过多年编程和在Java和C#Core中使用依赖注入,我可以补充:问题3非常开放,使用DI将允许您的代码:

  • 如果你改变你的构造函数,那么你就必须去搜索所有new ObjectModified(oldParams)添加新参数
  • 更容易测试,因为你可以注入"假对象"的依赖,避免了需要加载所有的系统和准备考试的状态,例如,如果你想查询一些代码依赖于当前小时,你可以在测试模式下连接假提供者,以便始终提供相同的小时或某个序列
  • 避免循环依赖,其中A类依赖于B而B取决于A,通常这更复杂,如

ClasssA - > ClasssB - > ClasssC - > ClasssA

当存在这种依赖关系时,你可以开始一个修改,然后修改使用它的类,依此类推......直到你发现自己修改了同一个类,所以你开始在一个循环中,因为它之间的通信路径你的对象很复杂.当您使用DI时,可以在早期检测到此循环,因此您可以重新考虑您的体系结构以避免这种生产力黑洞

DI是一个非常强大的工具,可以保持大项目的可维护性,现在存在于很多环境和框架中,因为它非常有用,如果这仍然不能说服你,你可以尝试在Spring boot,PlayFramework,Net Core中启动一个项目, Java EE,Ruby on Rails ......以及其他许多将其作为正常流程并构建中等大小的应用程序,然后在没有DI的情况下尝试