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'吗?
几乎没有init()需要单独方法的情况:
遗留API,你没有任何选择
初始化有一些副作用,例如开始a Thread,连接到som外部资源
这实际上具有更深层次的含义:当使用基于类的代理(通过cglib)时,基类的构造函数被调用两次(代理的第二次来自你的类) - init()方法在最终对象上只被调用一次.
你不应该在构造函数中执行虚拟调用(这实际上应该被编译器禁止...)
有时你必须使用setter/field injection(虽然我喜欢构造函数注入),例如当使用上述基于类的代理时
使用构造函数来执行对象所需的任何设置,就像正常/良好的面向对象设计一样?
这实际上并不是将所有初始化代码放在构造函数中的最佳实践.构造函数中的副作用使测试和模拟变得更加困难.而是专注于创建稳定和已知状态的对象.这样,您可以解耦创建管理连接池的对象并物理连接到该池.
BTW destroy()是一种没有析构函数的语言的祝福,因为它允许你感激地关闭外部资源,中断线程等.经常使用它.
你为什么需要它?
在设置了所有bean的属性之后调用init方法.如果bean需要对属性进行一些初始化或验证,而这些属性只能在设置了所有属性后才能完成,则通常需要这样做.(如果你尝试在没有"init"回调的情况下这样做,你会发现每个属性设置器都必须检查是否已经调用了其他setter.等等.如果只能在所有属性之后进行初始化,那么即使该策略也会失败已经设定了一个豆类循环.)
如果bean拥有需要显式释放的资源,则需要destroy方法; 例如文件句柄,网络套接字,数据库连接.
...像普通/良好的面向对象设计一样需要?
任何指示init和destroy事件/方法都是"错误"或"禁止"的设计方法都是不现实的,应该被忽略.事实上,面向对象的设计方法通常不会指明这一点.他们至多会说通常不需要这种东西.
此外,DI实际上在某种程度上改变了设计方法的规则...至少在初始化方面.特别是,通过外部化实例的"连接",它以经典的OO设计方法无法预期的方式从代码中抽出很多逻辑.如果有的话,这就是说需要根据依赖注入来重新审视经典的OO方法.
| 归档时间: |
|
| 查看次数: |
4518 次 |
| 最近记录: |