Custom provider

279 views
Skip to first unread message

jfz

unread,
Apr 14, 2007, 5:24:41 PM4/14/07
to google-guice
Is there an example of using Guice to instantiate/inject a DataSource,
or any third-party, object?

Equivalent Spring definition might be as follows:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-
method="close">
...
<property name="initialSize"><value>2</value></property>
<property name="username"><value>sa</value></property>
<property name="password"><value></value></property>
...
</bean>

Dhanji R. Prasanna

unread,
Apr 15, 2007, 12:29:18 AM4/15/07
to google...@googlegroups.com
you would have to use a Provider<BasicDataSource> for this and configure the values in code:

public class BDSProvider implements Provider<BasicDataSource> {
     @Inject @Named("ds.initial_size") int initialSize;
     @Inject @Named("ds.username") String username;
     //..

     public BasicDataSource get() {
          BasicDataSource source = new BasicDataSource();
          source.setInitialSize(initialSize);
          source.setUsername(username);

          //...etc.

          return source;
     }
}

Then bind the provider:

bind(BasicDataSource.class).toProvider(BDSProvider.class);

//and your externalized values from a props file or whatever
bindProperties()....

jfz

unread,
Apr 15, 2007, 12:49:32 AM4/15/07
to google-guice
thaks; I'll give a try.

Should something like this work and if so what is its disadvantage?

protected void configure() {
...
final BasicDataSource bds = new BasicDataSource();
bds.setUrl("url");bds.setUsername("uName");...
bind(BasicDataSource.class).toInstance(bds);
...
}

On Apr 15, 12:29 am, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:
> you would have to use a Provider<BasicDataSource> for this and configure the
> values in code:
>
> public class BDSProvider implements Provider<BasicDataSource> {
> @Inject @Named("ds.initial_size") int initialSize;
> @Inject @Named("ds.username") String username;
> //..
>
> public BasicDataSource get() {
> BasicDataSource source = new BasicDataSource();
> source.setInitialSize(initialSize);
> source.setUsername(username);
>
> //...etc.
>
> return source;
> }
>
> }
>
> Then bind the provider:
>
> bind(BasicDataSource.class).toProvider(BDSProvider.class);
>
> //and your externalized values from a props file or whatever
> bindProperties()....
>

Dhanji R. Prasanna

unread,
Apr 15, 2007, 1:01:02 AM4/15/07
to google...@googlegroups.com
yep that will work but it will mean the following:

- BDS is now a singleton (every injection will point to the same instance)
- BDS is eagerly instantiated (you may wish to wait until a service that is actually using it asks for it)
- You are cluttering module bindings with factory code (this really belongs in Provider or a similar artifact--such as a static factory method).
- You have internalized configuration settings like url and username which typically reside in a non-java file somewhere (means you have to rebuild your app into multiple profiles for multiple deployments with different settings)

Dhanji.

On 4/15/07, jfz <jf.z...@gmail.com> wrote:

jfz

unread,
Apr 15, 2007, 1:06:46 AM4/15/07
to google-guice
I was trying to avoid on more class at the expense of the items you
point out;

Thanks for the input Dhanji;

On Apr 15, 1:01 am, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:
> yep that will work but it will mean the following:
>
> - BDS is now a singleton (every injection will point to the same instance)
> - BDS is eagerly instantiated (you may wish to wait until a service that is
> actually using it asks for it)
> - You are cluttering module bindings with factory code (this really belongs
> in Provider or a similar artifact--such as a static factory method).
> - You have internalized configuration settings like url and username which
> typically reside in a non-java file somewhere (means you have to rebuild
> your app into multiple profiles for multiple deployments with different
> settings)
>
> Dhanji.
>

jfz

unread,
Apr 15, 2007, 3:45:35 PM4/15/07
to google-guice
Dhanji:

I reviewed your note and I still dislike generating a Provider class
for each non-annotated class.

How about exploring something like the line below using a Decorator
class and or equivalent bind.function.

bind(ISerice.class).to(bind.decorate(Service.class).buildProperties(..).in(Scopes.SINGLETON);

or something like that.

The static decorate function will use introspection to match
Properties, setXyx type.

This approach may not be applicable to all cases but quite useful for
most such as DataSource and Dao instances.

I find no problems with annotations but I am less inclined to produce
more classes other than Module(s) to effect DI and application
configuration via Property files.


On Apr 15, 1:01 am, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:
> yep that will work but it will mean the following:
>
> - BDS is now a singleton (every injection will point to the same instance)
> - BDS is eagerly instantiated (you may wish to wait until a service that is
> actually using it asks for it)
> - You are cluttering module bindings with factory code (this really belongs
> in Provider or a similar artifact--such as a static factory method).
> - You have internalized configuration settings like url and username which
> typically reside in a non-java file somewhere (means you have to rebuild
> your app into multiple profiles for multiple deployments with different
> settings)
>
> Dhanji.
>

Stuart McCulloch

unread,
Apr 15, 2007, 9:49:13 PM4/15/07
to google...@googlegroups.com
On 16/04/07, jfz <jf.z...@gmail.com> wrote:
>
> Dhanji:
>
> I reviewed your note and I still dislike generating a Provider class
> for each non-annotated class.
>

Just out of curiosity, what don't you like about using additional classes
to configure DI compared to XML or introspection? Both involve a bit of
typing and careful thought, but I honestly can't see what's so bad about
provider classes...

IMHO the benefit of writing your DI using Java code is that you get better
tool validation - plus most IDEs let you quickly create templates so you
can reduce the typing down to a few keystrokes.

I used to do this for J2EE entity beans (although in that case you needed
both Java code and XML!) and found IDE provided templates made it so
much easier for new devs to pick things up.


--
Cheers, Stuart

Dhanji R. Prasanna

unread,
Apr 15, 2007, 10:24:35 PM4/15/07
to google...@googlegroups.com
On 4/16/07, jfz <jf.z...@gmail.com> wrote:

The static decorate function will use introspection to match
Properties, setXyx type.


This may work for your particular case but IMO there is too much "magic" happening (you are binding by guessing property names via reflection). This type of magic is unpredictable and needs careful design and communication to fellow developers (what happens if the props files mismatch? does it fail silently? what about "optional" properties?)
 

I find no problems with annotations but I am less inclined to produce
more classes other than Module(s) to effect DI and application
configuration via Property files.

Providers are easy to write. They should be thought of as the equivalent of the bean descriptor xml in spring or service definition xml in hivemind. They are also typesafe, injectable themselves, and give you more flexibility when dealing with non-java metadata (can leverage core JSE or your own utilities for stuff like dates, collections whatever).

If you had a mandate about number of classes I would suggest pulling the guice configuration (Modules, Providers) out into a separate artifact.

Dhanji.

jfz

unread,
Apr 15, 2007, 11:20:52 PM4/15/07
to google-guice
Stuart:

The reason I am experimenting with Guice is that I like the idea of a
Module or Modules, using Java, used for DI and to configure an
Property files for configuration.

One place where using Java defines the dependencies of an application
and change, yes, compile it, to modify the behaviour overtime even
possibly done on-the-fly.

Provider classes are just that, additional classes that I prefer to
avoid; just additional things, classes, that detract from the
simplicity of Module(s) and annotations with attributes; I prefer also
to avoid additional Interface classes such as @Blue et al; annotation
with attributes via @Named is fine since the interface is provided as
part of Guice.

Others have gone beyond talk and written some interesting code to
address a similar concern.

Have a look at this url; I think Tim Peierls has proposed some
intersting options.

http://tembrel.blogspot.com/2007/04/guice-utility-for-binding-to-legacy.html

On Apr 15, 9:49 pm, "Stuart McCulloch" <mccu...@gmail.com> wrote:

Stuart McCulloch

unread,
Apr 15, 2007, 11:57:53 PM4/15/07
to google...@googlegroups.com
On 16/04/07, jfz <jf.z...@gmail.com> wrote:
>
> Stuart:
>
> The reason I am experimenting with Guice is that I like the idea of a
> Module or Modules, using Java, used for DI and to configure an
> Property files for configuration.
>

Me too - there are a lot of good ideas in Guice.

I guess I've been bitten many times by missing/misconfigured property
files that I find using Java for configuration refreshing - it's much more
self-documenting, and more flexible (eg. dynamic scope configuration)

Plus with OSGi (another interest of mine) it's much easier to version.

> One place where using Java defines the dependencies of an application
> and change, yes, compile it, to modify the behaviour overtime even
> possibly done on-the-fly.
>
> Provider classes are just that, additional classes that I prefer to
> avoid; just additional things, classes, that detract from the
> simplicity of Module(s) and annotations with attributes; I prefer also
> to avoid additional Interface classes such as @Blue et al; annotation
> with attributes via @Named is fine since the interface is provided as
> part of Guice.

This is fine, if that's your preference - although you should make sure
you're not just hiding complexity in the property files, where it's not so
obvious.

I mean things are usually complex for a reason and introspection 'magic'
just hides it from sight, whereas plain Java forces you to think about it.

>
> Others have gone beyond talk and written some interesting code to
> address a similar concern.
>

I'm coding as I write this ;) just haven't got round to posting any links...

> Have a look at this url; I think Tim Peierls has proposed some
> intersting options.
>
> http://tembrel.blogspot.com/2007/04/guice-utility-for-binding-to-legacy.html
>

Yep, Tim has provided some cool utility classes (perhaps there should be
a guice-lecagy or guice-utility jar provided alongside the core guice jar?)

It's just that I hear so much talk against providers, when it's really the
same as writing a configuration file, but in a language that everyone
already knows...

Ah well, I guess it's not everyone's cup of tea - must get back to coding :)


--
Cheers, Stuart

Reply all
Reply to author
Forward
0 new messages