Eelco Hillenius
unread,Sep 8, 2009, 5:01:54 AM9/8/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to google-guice
Hi,
I have two different data sources and I want them initialized through
properties files. When using Spring I would just instantiate the same
class twice with different parameters, but with Guice it is a little
bit less straightforward - at least initially, and in fact I already
like the end result better :-)
As I'm really just starting out with Guice, I'm wondering if the way
I'm going about it is the best way. So, I'd really appreciate it if
you could look at the following code fragment, and share whether you
think that's the best way to solve it, or how I can do it better.
If this is indeed the way to work with Guice, my next step would be to
either implement javax.sql.DataSource myself and wrap e.g.
com.mchange.v2.c3p0.ComboPooledDataSource (from 3cp0) or extend the
latter class directly and throw in a few Guice annotations for good
measure. Does that sound reasonable?
Thanks!
Eelco (code follows next):
defaults.properties:
udbDataSource.driverClassName=oracle.jdbc.driver.OracleDriver
udbDataSource.url=jdbc:oracle:thin:foo/bar:1526:baz
districtDataSource.driverClassName=oracle.jdbc.driver.OracleDriver
districtDataSource.url=jdbc:oracle:thin:hoi/pipeloi@localhost:
1526:oempf
Datasource base class:
public abstract class DataRef {
private final String driverClassName, url;
public DataRef(String driverClassName, String url) {
this.driverClassName = driverClassName;
this.url = url;
}
public String getDriverClassName() { return driverClassName; }
public String getUrl() { return url; }
public String toString() { return "{driver=" + driverClassName + ",
url=" + url + "}"; }
}
Two tagging annotations to differentiate between data source
instances:
@BindingAnnotation @Target( { FIELD, PARAMETER, METHOD }) @Retention
(RUNTIME)
public @interface UdbRef { }
@BindingAnnotation @Target( { FIELD, PARAMETER, METHOD }) @Retention
(RUNTIME)
public @interface DistrictRef { }
And then the data sources:
public class UdbDataRef extends DataRef {
@Inject
public UdbDataRef(
@Named("udbDataSource.driverClassName") String driverClassName,
@Named("udbDataSource.url") String url) {
super(driverClassName, url);
}
}
public class DistrictDataRef extends DataRef {
@Inject
public DistrictDataRef(
@Named("districtDataSource.driverClassName") String
driverClassName,
@Named("districtDataSource.url") String url) {
super(driverClassName, url);
}
}
A class that uses a specific data source:
public class Foo {
private final DataRef dataRef;
@Inject
public Foo(@UdbRef DataRef dataRef) {
this.dataRef = dataRef;
}
@Override
public String toString() {
return "dataRef: " + dataRef;
}
}
And finally the configuration and test:
public class Guice1Test {
private static class Bindings extends AbstractModule {
@Override
protected void configure() {
bind(DataRef.class).annotatedWith(DistrictRef.class).to
(DistrictDataRef.class);
bind(DataRef.class).annotatedWith(UdbRef.class).to
(UdbDataRef.class);
Properties properties = new Properties();
try {
properties.load(
Guice1Test.class.getResourceAsStream("defaults.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
Names.bindProperties(binder(), properties);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new Bindings());
Foo foo = injector.getInstance(Foo.class);
System.out.println(foo);
}
}