How do I use static factory method instead of constructor?

1,728 views
Skip to first unread message

Ben

unread,
Mar 13, 2007, 12:55:20 PM3/13/07
to google...@googlegroups.com
Is there a way to tell Guice that I want to use
"MyClass.newInstance(...)" to instantiate the class?

And more, can I direct Guice to use "Factorys.createMyInteraface()" to
instantiate an instance of MyInterface?

Ben.

Hani Suleiman

unread,
Mar 13, 2007, 1:00:10 PM3/13/07
to google...@googlegroups.com

On Mar 13, 2007, at 12:55 PM, Ben wrote:

>
> Is there a way to tell Guice that I want to use
> "MyClass.newInstance(...)" to instantiate the class?
>

What's the benefit of doing this instead of a constructor?

> And more, can I direct Guice to use "Factorys.createMyInteraface()" to
> instantiate an instance of MyInterface?
>

Why not just write a Provider, which is analogous to your factory?

ajoo....@gmail.com

unread,
Mar 13, 2007, 1:13:59 PM3/13/07
to google-guice
Ah. right. Provider should do everything I need here.

I was thinking about the lifecycle support.

With a static factory method or a Provider, the "init" thing looks
implementable in Guice.

For example:
<pre>
class MyClass {
@Inject
void setDep1(Dep1 dep1){}
@Inject
void setDep1(Dep2 dep2){}
@inject
//this should be called after all dependencies are injected.
void init(){}
}
</pre>
may be implemented as:
<pre>
class MyClass {
public static MyClass newInstance(Dep1 dep1, Dep2 dep2) {
MyClass mc = new MyClass();
mc.setDep1(dep1);
mc.setDep2(dep2);
mc.init();
return mc;
}
}
</pre>

And a custom Provider should be able to do this:
<pre>
class MyClassProvider implements Provider<MyClass> {
@Inject
MyClassProvider(Dep1 dep1, Dep2 dep2){...}
public MyClass get() {
return MyClass.newInstance(dep1, dep2);
}
}
</pre>

ajoo....@gmail.com

unread,
Mar 13, 2007, 1:57:05 PM3/13/07
to google-guice
Though Provider is relatively easy to use. I still feel it'll be nice
if I'm allowed to annotate static method with "@Inject" so that this
method is used as a "named constructor".

Is this already supported? Or maybe it's not as useful as I think it
is?


On Mar 13, 12:13 pm, "ajoo.em...@gmail.com" <ajoo.em...@gmail.com>
wrote:

Kevin Bourrillion

unread,
Mar 13, 2007, 4:15:03 PM3/13/07
to google...@googlegroups.com
It should be easier than all this!

class MyClass {
@Inject setDeps(Dep1 dep1, Dep2 dep2) {
setDep1(dep1);
setDep2(dep2);
// initialization goes here
}
}

... and you shouldn't need the provider. Or the static factory method. :-)

I still have not seen why this is preferable to constructor injection,
though, which has advantages including that the dep1 and dep2 fields
can be final...

K

Kevin Bourrillion

unread,
Mar 13, 2007, 4:19:35 PM3/13/07
to google...@googlegroups.com
FYI, @Inject on a static method means something completely different;
see Binder.requestStaticInjection().

http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html#requestStaticInjection(java.lang.Class...)

But regardless... I suppose I personally don't feel this would be
useful. We cover both ends of the spectrum: if you want to do things
the guicey way, have an injectable constructor; if you don't, write a
custom provider. So I don't think I see the value at this point in
addressing more various points along this guiciness spectrum.

As always, opinions subject to change in the face of evidence and
illustration...

K

Bob Lee

unread,
Mar 13, 2007, 5:08:44 PM3/13/07
to google...@googlegroups.com
On 3/13/07, Kevin Bourrillion <kevi...@gmail.com> wrote:

It should be easier than all this!

  class MyClass {
    @Inject setDeps(Dep1 dep1, Dep2 dep2) {
      setDep1(dep1);
      setDep2(dep2);
      // initialization goes here
    }
  }

Yeah, when I do this, I even like to name the method "initialize".

Bob

Kevin Bourrillion

unread,
Mar 13, 2007, 5:57:04 PM3/13/07
to google...@googlegroups.com
And I like to name mine with the same name as my class. And take out
the return type (which humorously it looks like I left out in my code
snippet anyway).

K

ajoo....@gmail.com

unread,
Mar 13, 2007, 6:31:09 PM3/13/07
to google-guice
I'm not really sure that allowing static factory method injection is a
very useful feature or not. Maybe if I always do the Guice way, I will
very rarely need it.

It just feels like having it will make Guice more like "do it your way
and I'll do my best to serve you" rather than "do it _the_ right way
or go away".

Anyway, this probably isn't important if it requires more complicated
implementation in Guice. :-)


On Mar 13, 4:57 pm, "Kevin Bourrillion" <kevin...@gmail.com> wrote:
> And I like to name mine with the same name as my class. And take out
> the return type (which humorously it looks like I left out in my code
> snippet anyway).
>
> K
>

> On 3/13/07, Bob Lee <crazy...@crazybob.org> wrote:

dha...@gmail.com

unread,
Mar 13, 2007, 11:03:52 PM3/13/07
to google-guice

On Mar 14, 7:57 am, "Kevin Bourrillion" <kevin...@gmail.com> wrote:
> And I like to name mine with the same name as my class. And take out
> the return type (which humorously it looks like I left out in my code
> snippet anyway).
>

=)
I agree entirely. constructor injection is better for many reasons not
the least of which is safe-publication (all fields injected in the
constructor can be declared final),
and a tight injection contract (cannot accidentally forget to inject
some setters because you forgot to annotate them or in spring, omit
<property> tags).

Afaic, the only real argument for setter injection over constructor-
inj (apart from readability of xml) was that you could do neat things
like autowire (in spring) more flexibly.
With custom/named annotations in guice, now that benefit is
effectively neutralized.

> K
>
> On 3/13/07, Bob Lee <crazy...@crazybob.org> wrote:

John Calcote

unread,
Apr 12, 2015, 3:52:52 PM4/12/15
to google...@googlegroups.com, ha...@formicary.net
The most significant benefit of this pattern is one which is much more obvious outside the scope of guice, and one which is used all the time. For instance, have you ever tried to design a class that runs itself (a run method) within a thread? It's nice when you create one of these objects to have the constructor simply start the thread and return. The problem is that you have to pass "this" to the thread start routine as static data, and it's a real issue if the OS happens to put your constructor to sleep after it's scheduled itself to be run, but before it returns, then the OS schedules your new thread to wake up and do something with your partially constructed object. Several IDEs (netbeans included) display a warning whenever 'this' is handed to an object in the constructor - it flags these as 'suspicious constructor arguments'. 

The usual way around this problem is to have a static factory method in your class that calls a private constructor to build your object and then initializes it with a call to a private init function that hands 'this' to the consumer object (e.g., thread). Now, the only way you can create your objects is by calling it's static factory method. So... the OP's question still stands, and for very good reason - is there a way to annotate your class so that guice will create it by calling a static factory instead of a constructor?

Thanks!
John

Stephan Classen

unread,
Apr 12, 2015, 4:23:14 PM4/12/15
to google...@googlegroups.com
I see two ways to achieve the same using no static factory methods.

1.
As Ben already suggested, create a provider. You can even call a static factory method from the provider.
Or you can inline the static factory method if it is only called from the provider. But be aware that an instance created with a custom provider will not support method interception using guices interceptors.

public class FooProvider<Foo> {
    public Foo get() {
        return Foo.createInstance();
    }
}

and then bind Foo as follows:

bind(Foo.class).toProvider(FooProvider.class);

2.
Use Onami Lifecycle to have a post construct method executed after the constructor has finished but before the created object is injected.
see:  https://onami.apache.org/lifecycle/org.apache.onami.lifecycle.jsr250/index.html
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/8bb1b5e8-9dba-4078-a2a2-9572d11c5f00%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages