2015-04-28 53 views
2

根據不可變對象的定義(see this question),我不確定是否將Spring DAO的setter作爲唯一一個用途來確保不可變性。例如(數據源屬性):Spring DAO和不可變對象

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的?

+0

你是什麼意思只有一次使用? – Adelin

+0

我的意思是一個setter只能使用一次(當IoC初始化Spring上下文時),這樣對象不會被其他bean或對象改變。 –

+0

由於'JdbcDaoSupport#setDataSource'是最終的,你不能'@ Override'。 – dit

回答

1

如果你看一下執行的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; 
4

安裝人員不止一次使用,而構造函數則不是。

當涉及到春天,最好通過構造器來設置所有必需的豆類:

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

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

其次,你可以簡單地添加必需的屬性,這將使你的代碼更短。 Spring將確保提供一個DataSource的bean。

UPDATE: 如果你仍然想使用制定者,比你不需要另一個標誌,只需選中= NULL條件:

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

實際上你不需要一個變量'DataSource'。看看'JdbcDaoSupport#getDataSource()' – dit

+0

不,你沒有:)我只是想解釋一下,當你只想設置一次變量時,使用final可以是一個不錯的選擇。 – Beri

+0

好的,我明白了。但是如果我不提供setter方法,我不需要做最後的決定。對? – dit

0

不可變對象是簡單對象,其狀態(對象的數據)施工後不能改變。來自JDK的不可變對象的示例包括String和Integer。

爲確保MySpringPojoDAO的可變性首先使它成爲最終的,所以它不能延長,不要引入可以改變其內部狀態的方法,如setters。這就是我喜歡關於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!!! 
    } 

} 

check this out

0

不變對象

的對象被認爲是不可變,如果它被構造後其狀態不能改變。最大程度地依賴不可變對象被廣泛接受爲創建簡單可靠代碼的合理策略。

不可變類 - 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。陣列等

恕我直言,不變性是一個很好的候選人的考慮 - 同時定義一個特定的「類型」(實體 - Pojo類型)的對象。因此,儘管沒有人會阻止你創建你的'MySpringPojoDAO'不可變 - 如果你實現'MySpringPojo'不可變,並且DAO可變,那將更有意義。 (或者可能是最後的)

讀 - https://stackoverflow.com/a/5124214/760393