You may have heard of Google's
Guice<http://code.google.com/p/google-guice/>(juice).
I decided to try Guice for a small project. It is simple although it takes
sometime to assimilate its concept and associated object binding
'language',
all in java, no XML.
I'm using a properties file to define the DataSource and iBatis parameters;
will use a properties file to externalize any Guice configuration; Guice
supports resolving external entries via a properties-file.
Therefore, a couple of properties-files and a Guice Module(s) result in
autonated DI and central object configuration for an application via a
Guice
Module class. It helps document and simplify the application. The more I
use it the more I seem to realize its benefit that used for configuring
Click and iBatis result in a good combination of technologies for web
development.
Downsides:
1. Dependency on Google Guice imports
2. The more you use it, the more you create a dependency for its
function; in my case, I find it very useful despite the labour with the
Provider class to use iBatis.
3. Annotations. Yes, annotations are needed to effect its function.
Spring externalizes it and avoids touching the subject code.
4. Provider class. To define a dependency for a class not annotated,
an exteral and/or 3rd-party resource, iBatis in my case, I needed to
define
a Provider class; see it below.
I used Guice as follows; there may be a better way; I placed the Guice
Injector object in Session scope via onInit() method on a Page class;
this Page is extended by the apps Page objects.
super Page class; ZPage
@Inject IDao dao; // used by sub-Page objects for a IDao reference
public void onInit() {
getContext().getSession();
Injector injector = (Injector)
getContext().getSessionAttribute(zginjector);
if( injector == null ) {
injector = Guice.createInjector(new GModule());
getContext().setSessionAttribute(zginjector,injector);
}
injector.injectMembers(this); // resolve annotated dependencies
}
GModule is simple: (What is to be injected)
public class GModule extends AbstractModule {
protected void configure() {
bind(IDao.class).to(ZDao.class).in(Scopes.SINGLETON);
bind(SqlMapClient.class).toProvider(SqlMapClientP.class ).in(
Scopes.SINGLETON);
bindConstant().annotatedWith(named("ibatis.configXml"))
.to("iris/conf/sqlMapConfig.xml");
}
}
In a Page extended from ZPage I can then inject, reference, the Singlenton
Dao object as
(Where to inject defined by @Inject annotations). There are alternate
ways to do it; using it by this simple annotation a setter method is
unneeded, Guice injects the IDao implementation defined in the Module class
(named GModule above).
....
@Inject IDao dao;
...
this.R = (List) this.dao.getAll();
iBatis Guice Provider class: define a class using Guice Provider Interface
to use an external class, iBatis SqlMapClient, so that Guice can use it.
public class SqlMapClientP implements Provider {
private static SqlMapClient sqlMapClient;
@Inject @Named("ibatis.configXml") String configXml;
public SqlMapClient get() {
if(sqlMapClient != null) return sqlMapClient;
try {
Reader reader = Resources.getResourceAsReader(configXml);
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
}catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("SqlMapClientP unable to create
instance." + e);
}
return sqlMapClient;
}
}
--
jfz.