How to override BasicDataSource for Spring and Hibernate correctly

I currently have a main data source in Spring:

<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost/test?relaxAutoCommit=true" />
    ...
</bean>

Now I need to provide a custom data source based on the server environment (not config), for which I need to calculate the fields driverClassNameand urlbased on some condition.

I tried to override the method createDataSource():

public class MyDataSource extends BasicDataSource {

    @Override
    protected synchronized DataSource createDataSource() throws SQLException {
        if(condition) {
            super.setDriverClassName("com.mysql.jdbc.Driver");
            super.setUrl("jdbc:mysql://localhost/test?relaxAutoCommit=true");
        } else {
            //...
        }
        return super.createDataSource();
    }
}

Which works, but I noticed that it createDataSource()receives a call every time a request is made (?), So I would prefer to move my testing conditions elsewhere.

setDriverClassName() setUrl(), , , Spring, , :

<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="whatever" />
    <property name="url" value="whatever" />
    ...
</bean>

.

?

+3
1

BasicDataSource. - , , .

:

  • ( )

    public class MyDataSource implements DataSource {
        private BasicDataSource target = new BasicDataSource();
        public MyDataSource() {
            if (condition) {
                target.setDriverClassName("com.mysql.jdbc.Driver");                
                target.setUrl("jdbc:mysql://localhost/test?relaxAutoCommit=true"); 
            } else { ... }
        }
        public Connection getConnection() {
            return target.getConnection();
        }
        ... etc ...
    }
    
  • factory ( , ).

     public class MyDataSourceFactory {
        public DataSource createDataSource() {
            BasicDataSource target = new BasicDataSource();
            if (condition) {
                target.setDriverClassName("com.mysql.jdbc.Driver");                
                target.setUrl("jdbc:mysql://localhost/test?relaxAutoCommit=true"); 
            } else { ... }
            return target;
        }
    }
    

    .

    <bean id = "factory" class = "MyDataSourceFactory" />
    <bean id = "dbcpDataSource" 
         factory-bean = "factory" factory-method = "createDataSource">
         <property ... />
    </bean>
    

EDIT: , , factory, Spring bean.

, , , Spring, Spring .

+4

Source: https://habr.com/ru/post/1781313/


All Articles