Pet*_*sik 16 java dependency-injection cdi
我在这里找不到任何合理的答案所以我希望它不是重复的.那么为什么我更喜欢setter或构造函数注入而不是简单
@Inject
MyBean bean;
Run Code Online (Sandbox Code Playgroud)
如果你需要在类初始化期间对注入的bean执行某些操作,我会使用构造函数注入
public void MyBean(@Inject OtherBean bean) {
doSomeInit(bean);
//I don't need to use @PostConstruct now
}
Run Code Online (Sandbox Code Playgroud)
但是,它几乎和@PostConstruct方法一样,我根本没有得到setter注入,它不仅仅是Spring和其他DI框架之后的遗物吗?
Ren*_*ink 20
构造函数和属性注入使您可以轻松地在非CDI环境中初始化对象,例如单元测试.
在非CDI环境中,您仍然可以通过传递构造函数arg来简单地使用该对象.
OtherBean b = ....;
new MyBean(b);
Run Code Online (Sandbox Code Playgroud)
如果您只是使用场注入,通常必须使用反射来访问该字段,因为字段通常是私有的.
如果使用属性注入,也可以在setter中编写代码.例如验证代码或清除内部缓存,其中包含从setter修改的属性派生的值.您想要做什么取决于您的实施需求.
在面向对象的编程中,对象在构造之后必须处于有效状态,并且每个方法调用都将状态更改为另一个有效状态.
对于setter注入,这意味着您可能需要更复杂的状态处理,因为对象在构造之后应该处于有效状态,即使尚未调用setter也是如此.因此,即使未设置属性,对象也必须处于有效状态.例如,使用默认值或null对象.
如果对象的存在与属性之间存在依赖关系,则该属性应该是构造函数参数.这也将使代码更加干净,因为如果使用构造函数参数,则需要记录依赖项.
所以不要写这样的课
public class CustomerDaoImpl implements CustomerDao {
private DataSource dataSource;
public Customer findById(String id){
checkDataSource();
Connection con = dataSource.getConnection();
...
return customer;
}
private void checkDataSource(){
if(this.dataSource == null){
throw new IllegalStateException("dataSource is not set");
}
}
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
}
Run Code Online (Sandbox Code Playgroud)
你应该使用构造函数注入
public class CustomerDaoImpl implements CustomerDao {
private DataSource dataSource;
public CustomerDaoImpl(DataSource dataSource){
if(dataSource == null){
throw new IllegalArgumentException("Parameter dataSource must not be null");
}
this.dataSource = dataSource;
}
public Customer findById(String id) {
Customer customer = null;
// We can be sure that the dataSource is not null
Connection con = dataSource.getConnection();
...
return customer;
}
}
Run Code Online (Sandbox Code Playgroud)
PS:我的博客pojos和java bean之间的区别更详细地解释了我的结论.
| 归档时间: |
|
| 查看次数: |
11136 次 |
| 最近记录: |