2015-09-11 166 views
0

我已經搜索並找不到任何示例,它們會向我顯示更好的方法來做到這一點,但在Spring/Spring引導代碼中,有通用的構建器,但構建器本身似乎以編程方式應用了屬性。下面是一些代碼嘗試配置2個Oracle連接池數據來源:對構建器使用@ConfigurationProperties的最佳方式是什麼?

import oracle.ucp.jdbc.PoolDataSourceFactory; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.boot.context.properties.EnableConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 

import javax.sql.DataSource; 
import java.sql.SQLException; 


@Configuration 
@EnableConfigurationProperties 
@ConditionalOnClass(PoolDataSourceFactory.class) 
public class PersistenceAutoConfiguration { 

    @Bean (name = "readWriteDataSource") 
    public DataSource getReadWriteDataSource() throws SQLException { 
     OracleUcpDataSourceProperties rwProperties = getReadWriteProperties(); 

     return OracleUcpDataSourceBuilder.create() 
       .connectionFactoryClassName(rwProperties.getConnectionFactoryClassName()) 
       .url(rwProperties.getUrl()) 
       .user(rwProperties.getUser()) 
       .password(rwProperties.getPassword()) 
       .initialPoolSize(rwProperties.getInitialPoolSize()) 
       .minPoolSize(rwProperties.getMinPoolSize()) 
       .maxPoolSize(rwProperties.getMaxPoolSize()) 
       .connectionWaitTimeout(rwProperties.getConnectionWaitTimeout()) 
       .inactiveConnectionTimeout(rwProperties.getInactiveConnectionTimeout()) 
       .maxIdleTime(rwProperties.getMaxIdleTime()) 
       .build(); 
    } 

    @Bean (name = "readOnlyDataSource") 
    public DataSource getReadOnlyDataSource() throws SQLException { 
     OracleUcpDataSourceProperties roProperties = getReadOnlyProperties(); 

     return OracleUcpDataSourceBuilder.create() 
       .connectionFactoryClassName(roProperties.getConnectionFactoryClassName()) 
       .url(roProperties.getUrl()) 
       .user(roProperties.getUser()) 
       .password(roProperties.getPassword()) 
       .initialPoolSize(roProperties.getInitialPoolSize()) 
       .minPoolSize(roProperties.getMinPoolSize()) 
       .maxPoolSize(roProperties.getMaxPoolSize()) 
       .connectionWaitTimeout(roProperties.getConnectionWaitTimeout()) 
       .inactiveConnectionTimeout(roProperties.getInactiveConnectionTimeout()) 
       .maxIdleTime(roProperties.getMaxIdleTime()) 
       .build(); 
    } 

    @ConfigurationProperties(prefix = "datasource.readwrite") 
    @Bean(name = "readWriteProperties") 
    protected OracleUcpDataSourceProperties getReadWriteProperties() { 
     return new OracleUcpDataSourceProperties(); 
    } 

    @ConfigurationProperties(prefix = "datasource.readonly") 
    @Bean(name = "readOnlyProperties") 
    protected OracleUcpDataSourceProperties getReadOnlyProperties() { 
     return new OracleUcpDataSourceProperties(); 
    } 
} 

public class OracleUcpDataSourceProperties { 
    private String connectionFactoryClassName; 
    private String url; 
    private String user; 
    private String password; 
    private int initialPoolSize; 
    private int minPoolSize; 
    private int maxPoolSize; 
    private int connectionWaitTimeout; 
    private int inactiveConnectionTimeout; 
    private int maxIdleTime; 
    private Boolean validateConnectionOnBorrow; 


    public String getConnectionFactoryClassName() { 
     return connectionFactoryClassName; 
    } 

    public void setConnectionFactoryClassName(String connectionFactoryClassName) { 
     this.connectionFactoryClassName = connectionFactoryClassName; 
    } 

    public String getUrl() { 
     return url; 
    } 

    public void setUrl(String url) { 
     this.url = url; 
    } 

    public String getUser() { 
     return user; 
    } 

    public void setUser(String user) { 
     this.user = user; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public int getInitialPoolSize() { 
     return initialPoolSize; 
    } 

    public void setInitialPoolSize(int initialPoolSize) { 
     this.initialPoolSize = initialPoolSize; 
    } 

    public int getMinPoolSize() { 
     return minPoolSize; 
    } 

    public void setMinPoolSize(int minPoolSize) { 
     this.minPoolSize = minPoolSize; 
    } 

    public int getMaxPoolSize() { 
     return maxPoolSize; 
    } 

    public void setMaxPoolSize(int maxPoolSize) { 
     this.maxPoolSize = maxPoolSize; 
    } 

    public int getConnectionWaitTimeout() { 
     return connectionWaitTimeout; 
    } 

    public void setConnectionWaitTimeout(int connectionWaitTimeout) { 
     this.connectionWaitTimeout = connectionWaitTimeout; 
    } 

    public int getInactiveConnectionTimeout() { 
     return inactiveConnectionTimeout; 
    } 

    public void setInactiveConnectionTimeout(int inactiveConnectionTimeout) { 
     this.inactiveConnectionTimeout = inactiveConnectionTimeout; 
    } 

    public int getMaxIdleTime() { 
     return maxIdleTime; 
    } 

    public void setMaxIdleTime(int maxIdleTime) { 
     this.maxIdleTime = maxIdleTime; 
    } 

    public Boolean getValidateConnectionOnBorrow() { 
     return validateConnectionOnBorrow; 
    } 

    public void setValidateConnectionOnBorrow(Boolean validateConnectionOnBorrow) { 
     this.validateConnectionOnBorrow = validateConnectionOnBorrow; 
    } 
} 

import oracle.ucp.jdbc.PoolDataSource; 
import oracle.ucp.jdbc.PoolDataSourceFactory; 

import java.sql.SQLException; 

public class OracleUcpDataSourceBuilder { 
    private PoolDataSource pds; 

    /** 
    * This will grab the pool factory and initialize it. 
    */ 
    public OracleUcpDataSourceBuilder() throws SQLException { 
     pds = PoolDataSourceFactory.getPoolDataSource(); 
    } 

    public static OracleUcpDataSourceBuilder create() throws SQLException { 
     return new OracleUcpDataSourceBuilder(); 
    } 

    public OracleUcpDataSourceBuilder connectionFactoryClassName(String connectionFactoryClassName) throws SQLException { 
     pds.setConnectionFactoryClassName(connectionFactoryClassName); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder url(String url) throws SQLException { 
     pds.setURL(url); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder user(String user) throws SQLException { 
     pds.setUser(user); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder password(String password) throws SQLException { 
     pds.setPassword(password); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder initialPoolSize(int initialPoolSize) throws SQLException { 
     pds.setInitialPoolSize(initialPoolSize); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder minPoolSize(int minPoolSize) throws SQLException { 
     pds.setMinPoolSize(minPoolSize); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder maxPoolSize(int maxPoolSize) throws SQLException { 
     pds.setMaxPoolSize(maxPoolSize); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder connectionWaitTimeout(int connectionWaitTimeout) throws SQLException { 
     pds.setConnectionWaitTimeout(connectionWaitTimeout); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder inactiveConnectionTimeout(int inactiveConnectionTime) throws SQLException { 
     pds.setInactiveConnectionTimeout(inactiveConnectionTime); 
     return this; 
    } 

    public OracleUcpDataSourceBuilder maxIdleTime(int maxIdleTime) throws SQLException { 
     pds.setMaxIdleTime(maxIdleTime); 
     return this; 
    } 

    public PoolDataSource build() { 
     return pds; 
    } 
} 

最好,我希望能夠直接應用屬性在一個地方給建造者。這可能嗎?我需要做些什麼改變?

謝謝...

回答

0

這是你的建設者,先生

public class OracleUcpDataSourceBuilder { 

private Map<String, String> properties = new HashMap<String, String>(); 
private static final String[] REQ_PROPERTIES = new String[] {"username", "password", "URL"}; 

public static OracleUcpDataSourceBuilder create() { 
    return new OracleUcpDataSourceBuilder(); 
} 

public DataSource build() { 
    for (String prop : REQ_PROPERTIES) { 
     Assert.notNull(properties.get(prop), "Property is required:" + prop); 
    } 
    PoolDataSource result = PoolDataSourceFactory.getPoolDataSource(); 
    bind(result); 
    return result; 
} 

private void bind(DataSource result) { 
    MutablePropertyValues properties = new MutablePropertyValues(this.properties); 
    new RelaxedDataBinder(result).bind(properties); 
} 

public OracleUcpDataSourceBuilder URL(String url) { 
    this.properties.put("URL", url); 
    return this; 
} 

public OracleUcpDataSourceBuilder username(String username) { 
    this.properties.put("username", username); 
    return this; 
} 

public OracleUcpDataSourceBuilder password(String password) { 
    this.properties.put("password", password); 
    return this; 
} 

} 

只是bean定義是這樣的:

@Bean (name = "readOnlyDataSource") 
@ConfigurationProperties(prefix = "datasource.readonly") 
public DataSource getReadOnlyDataSource() { 
    return OracleUcpDataSourceBuilder.create().build(); 
} 

只要確保屬性名稱都是正確的。春天會照顧其餘的。

注意:我使用DataSourceBuilder或Spring作爲參考..您也可以查看它的源代碼。

編輯:添加了一些方法,以確保一些屬性配置。但是這樣,您需要手動設置這些屬性以確保它們可用。

+0

您如何製作所需的一些屬性並使用此方法添加驗證? –

+0

只需對我的回答進行一些編輯即可。小故事,如果你真的想確定,你需要手動定義它們。或者,我想這可能是有用的,你可以使用你的ConfigurationProp。方法,將所有屬性定義爲setter,並使用我給出的Builder。它應該工作:我注入這個PooledDataSource&看到屬性被分配。 –

+0

另外,如果你使用配置。屬性,你可以把@NotNull註釋,以確保那些道具。被定義。 –

相關問題