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