springdao和不可变对象

lrpiutwd  于 2021-07-13  发布在  Java
关注(0)|答案(4)|浏览(366)

根据不可变对象的定义(请看这个问题),我不太确定将spring dao的setter作为唯一用途是否是确保不可变性的一种方法。例如(数据源属性):

public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

   private boolean dataSourceSet = false;

   @Override
   public void setDataSource(DataSource dataSource){

       if (dataSourceSet) {
             throw new IllegalStateException("...");
       }

       dataSourceSet = true;
       this.dataSource = dataSource;
       }
   }

}

如果是错误的,那么使用spring框架或ioc来确保不变性的方法是什么?

3yhwsihp

3yhwsihp1#

如果您查看jdbcdaosupport的实现,您会发现:

public abstract class JdbcDaoSupport extends DaoSupport {

    private JdbcTemplate jdbcTemplate;

    /**
     * Set the JDBC DataSource to be used by this DAO.
     */
    public final void setDataSource(DataSource dataSource) {
        if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
            this.jdbcTemplate = createJdbcTemplate(dataSource);
            initTemplateConfig();
        }
    }

    /**
    * Return the JDBC DataSource used by this DAO.
    */
    public final DataSource getDataSource() {
        return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
    }

    [...]

}
``` `JdbcDaoSupport#setDataSource` 是终局的。不能重写此方法。这意味着你必须这样做:

public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

@Autowired
public MySpringPojoDAO (DataSource dataSource){
    setDataSource(dataSource); // JdbcDaoSupport#setDataSource(..)
}

[...]

}

所以让spring像这样处理豆子的生命周期 `DataSource` 为你。决不应手动创建的示例 `MySpringPojoDAO` . 改用:

@Autowired
private MySpringPojoDAO _myDao;

p8ekf7hl

p8ekf7hl2#

setter可以被多次使用,而constructor则不能。
对于spring,最好通过constructor设置所有必需的bean:

final DataSource dataSource;// will force this property to be set only once

@Autowired(required=true)
public MySpringPojoDAO (DataSource dataSource){
   this.dataSource = dataSource;
}

其次,您可以简单地添加所需的属性,这将使您的代码更短。spring将确保提供一个数据源bean。
更新:如果您仍然想使用setter,那么您不需要另一个标志,只需检查一下=空条件:

@Override
   public void setDataSource(DataSource dataSource){
       if (this.dataSource != null) { // has been already set
             throw new IllegalStateException("...");
       }
       this.dataSource = dataSource;
   }
aij0ehis

aij0ehis3#

不可变对象只是其状态(对象的数据)在构造后不能更改的对象。jdk中的不可变对象包括string和integer。
以确保 MySpringPojoDAO 首先使它成为最终的,这样它就不能被扩展;其次,不要引入像setter那样可以改变其内部状态的方法。这就是我喜欢的spring和guice依赖注入,你可以注入构造函数。

final public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

   // private boolean dataSourceSet = false; 

@Autowired
public MySpringPojoDAO (DataSource dataSource){
this.dataSource= dataSource
}
   /* @Override
   public void setDataSource(DataSource dataSource){

       if (dataSourceSet) {
             throw new IllegalStateException("...");
       }

       dataSourceSet = true;
       this.dataSource = dataSource;
       } */ 
       //don't use setters you'll need synchronization!!! 
   }

}

看看这个

pieyvz9o

pieyvz9o4#

不可变对象
如果一个对象在构造之后状态不能改变,那么它就被认为是不可变的。对于创建简单、可靠的代码来说,最大限度地依赖于不可变对象是一种被广泛接受的合理策略。
不可变类-java.lang.string、java.lang.integer、java.lang.byte、java.lang.character、java.lang.short、java.lang.boolean、java.lang.long、java.lang.double、java.lang.float。。。等
可能是/可能不是最终的类,但并不完全符合(im)可变性的要求—java.util.collections、java.util.arrays等。
在定义对象的特定“类型”(实体-pojo类型)时,不变性是一个很好的候选考虑因素。因此,虽然没有人会阻止您创建“myspringpojodao”不可变,但如果您实现“myspringpojo”不可变,而dao是可变的,那么就更有意义了(或可能是最终的)
阅读-https://stackoverflow.com/a/5124214/760393

相关问题