为什么Spring依赖注入有init-method?

Ben*_*key 4 java spring dependency-injection

我来自.NET背景,使用依赖注入容器,如Unity,Ninject,Castle Windsor等.最近我开始学习使用Spring的依赖注入功能来实现Java.

在学习Spring时,我已经看到可以在bean XML配置上指定'init-method'和'destroy-method'的概念.

指定'init-method'的目的似乎是在bean创建时进行任何你可能想要做的设置.这是我感到困惑的地方.为什么你需要一个单独的方法来执行设置,而不是只使用构造函数来执行对象所需的任何设置,就像正常/良好的面向对象设计所指定的那样?

换句话说,如果一个类需要依赖,那么它不应该被注入你知道已被调用的构造函数中,而对象可以存在于一个状态而不需要调用它的'init-method'吗?

Tom*_*icz 9

几乎没有init()需要单独方法的情况:

  • 遗留API,你没有任何选择

  • 初始化有一些副作用,例如开始a Thread,连接到som外部资源

    这实际上具有更深层次的含义:当使用基于类的代理(通过)时,基类的构造函数被调用两次(代理的第二次来自你的类) - init()方法在最终对象上只被调用一次.

  • 你不应该在构造函数中执行虚拟调用(这实际上应该被编译器禁止...)

  • 有时你必须使用setter/field injection(虽然我喜欢构造函数注入),例如当使用上述基于类的代理时

使用构造函数来执行对象所需的任何设置,就像正常/良好的面向对象设计一样?

这实际上并不是将所有初始化代码放在构造函数中的最佳实践.构造函数中的副作用使测试和模拟变得更加困难.而是专注于创建稳定已知状态的对象.这样,您可以解耦创建管理连接池的对象并物理连接到该池.

BTW destroy()是一种没有析构函数的语言的祝福,因为它允许你感激地关闭外部资源,中断线程等.经常使用它.


Ste*_*n C 5

你为什么需要它?

在设置了所有bean的属性之后调用init方法.如果bean需要对属性进行一些初始化或验证,而这些属性只能在设置了所有属性后才能完成,则通常需要这样做.(如果你尝试在没有"init"回调的情况下这样做,你会发现每个属性设置器都必须检查是否已经调用了其他setter.等等.如果只能在所有属性之后进行初始化,那么即使该策略也会失败已经设定了一个豆类循环.)

如果bean拥有需要显式释放的资源,则需要destroy方法; 例如文件句柄,网络套接字,数据库连接.

...像普通/良好的面向对象设计一样需要?

任何指示init和destroy事件/方法都是"错误"或"禁止"的设计方法都是不现实的,应该被忽略.事实上,面向对象的设计方法通常不会指明这一点.他们至多会说通常不需要这种东西.

此外,DI实际上在某种程度上改变了设计方法的规则...至少在初始化方面.特别是,通过外部化实例的"连接",它以经典的OO设计方法无法预期的方式从代码中抽出很多逻辑.如果有的话,这就是说需要根据依赖注入来重新审视经典的OO方法.