Featured post
java - How to correctly override BasicDataSource for Spring and Hibernate -
currently have following basic 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 need provide custom data source based on server environment (not config), need calculate driverclassname
, url
fields based on condition.
i tried overriding createdatasource()
method:
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, noticed createdatasource()
getting called each time query executed(?), rather move condition testing elsewhere.
i tried overriding setdriverclassname()
, seturl()
works , getting called once can tell, need provide values in spring configuration in order trigger setters not called otherwise:
<bean id="dbcpdatasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close"> <property name="driverclassname" value="whatever" /> <property name="url" value="whatever" /> ... </bean>
which might confusing.
are there better solutions?
there no need extend basicdatasource
. inheritance strongest form of coupling , should avoided unless have real reason use it.
you have 2 options:
create wrapper (use composition instead of inheritance)
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 ... }
create factory (since need customize creation phase of object, don't need control whole lifetime of it).
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: note still can configure object obtained factory regular spring bean.
also if condition simple enough, can avoid writing own code @ using declarative approaches provided spring, such spring expression language.
- Get link
- X
- Other Apps
Comments
Post a Comment