I have a question:
Usually in Guice I use bind(classe).to(another_class_Implementation) ...
However I found in a code source that they have used bind(class) only ( without the part ".to(another_class_Implementation)" ) ...
What does this mean ( bind(class) without "to or as" ) ?
Here is the part of code in question:
public class RestModule extends AbstractModule {
#Override
protected void configure() {
bind(RootResource.class);
bind(DeveloperUtilsRedirector.class);
bind(M34Repository.class).to(M34RepositoryImpl.class);
bind(IGARepository.class).to(IGARepositoryImpl.class);
Answers are appreciated
A bind statement without a to is called an Untargeted Binding (misspelled as "Untargetted Bindings" in the wiki URL) in the Guice docs. From that wiki page:
You may create bindings without specifying a target. This is most useful for concrete classes and types annotated by either #ImplementedBy or #ProvidedBy. An untargetted [sic] binding informs the injector about a type, so it may prepare dependencies eagerly.
You'll see this in Guice for three purposes:
Slight performance improvement via eager loading.
When Guice encounters a dependency that it doesn't have a binding for (say, class A), it inspects the class to see if it can be injected via an #Inject-annotated or zero-arg public constructor. If so, Guice creates a Just-In-Time binding (or "implicit binding"). This is done through reflection, and may cause a cascade of other bindings (requesting A inspects A, then A's dependency B, then B's dependency C, and so forth), which can cause some runtime slowdown.
By pre-emptively making an untargeted binding, you inform Guice about an injectable class, which allow it to pay that reflection cost at startup for more predictable performance.
Guice will throw an exception if it cannot create the object you inject, but in the case of #ImplementedBy or #ProvidedBy (or getInstance or injectMembers) Guice will not fail if it hasn't inspected the class with the missing binding yet. By listing classes you use, Guice will pre-analyze those objects as in (1), but will also recognize at app startup that a binding is missing. This may be handy during development, especially if you are injecting an object with getInstance or injectMembers long after application startup; you might prefer that failure to happen immediately.
Though implicit bindings are enabled by default, they can be disabled through requireExplicitBindings. This means that any injected classes need to have associated bindings, including classes with eligible constructors. An untargeted binding would resolve that situation easily.
Related
In Guice, when you indicate the lifetime of a certain instance, you will use a scoping annotation like bind(Applebees.class).in(Singleton.class);.
Or you appear to be able to use scope instances like
bind(UserPreferences.class)
.toProvider(UserPreferencesProvider.class)
.in(ServletScopes.REQUEST);
And officially Guice recommends the former approach because the former approach allows us to reuse the Module class.
But I am not sure of the point. My assumption is like this, so please check if this is right.
Scope instances is the term of Servelet, so if you adopt scope instances instead of scoping annotations, the Module class is only applicable to the Servelet. On the other hand, if you use scoping annotations, you can reuse your Module class unless you abandon Guice.
So, is this right? Could you check?
I believe your understanding is correct, but there's a little subtlety about what kind of reuse would be affected.
You're probably referring to this text from the Guice wiki on Scopes (emphasis mine):
The in() clause accepts either a scoping annotation like RequestScoped.class and also Scope instances like ServletScopes.REQUEST:
bind(UserPreferences.class)
.toProvider(UserPreferencesProvider.class)
.in(ServletScopes.REQUEST);
The annotation is preferred because it allows the module to be reused in different types of applications. For example, an #RequestScoped object could be scoped to the HTTP request in a web app and to the RPC when it's in an API server.
Even with Guice's servlet-specific scopes, you can choose between the Scope instance ServletScopes.REQUEST and the #RequestScoped annotation, and choose between in(Scope scope) and in(Class scopeAnnotation) accordingly (see ScopedBindingBuilder). Nearly every scope should have a corresponding annotation, as they are especially useful on classes and #Provides methods.
It's important to realize here that there's always a Scope instance that actually implements the scoping behavior (specifically, wrapping an unscoped Provider so that it can return already-returned instances in the right conditions). To associate an annotation to a Scope instance, you need to make sure that a module calls bindScope, which accepts the Scope annotation class and the Scope instance; for Servlets, Guice has this binding automatically installed via InternalServletModule.
#Override
protected void configure() {
bindScope(RequestScoped.class, REQUEST);
bindScope(SessionScoped.class, SESSION);
// ...
}
So what's the advantage of using in(Class scopeAnnotation)? When binding to a Scope instance, you are telling Guice exactly which Scope instance you want to use, rather than allowing the user an opportunity to use bindScope to bind the annotation to a different Scope instance. In the example I bolded above, you can imagine using the same Module without using the actual Guice servlet extensions (other than the annotations), but this would only be possible if you bind to annotation classes and then call bindScope yourself. If you bind using in(Scope), you'll need to change that line or write a new Module.
This is especially important for your own custom Scope instances and annotations, because it allows you to change your Scoping behavior consistently across your application:
#Override public void configure() {
// BAD: To change the scope, you'll need to change three lines.
// If you don't change all three together, you'll get inconsistent behavior.
bind(A.class).to(AImpl.class).in(MyScope.INSTANCE);
bind(B.class).to(BImpl.class).in(MyScope.INSTANCE);
bindScope(AScoped.class, MyScope.INSTANCE);
}
#Override public void configure() {
// GOOD: To change the scope, you can change one line, and optionally
// extract that line to a separate Module.
bind(A.class).to(AImpl.class).in(AScoped.class);
bind(B.class).to(BImpl.class).in(AScoped.class);
bindScope(AScoped.class, MyScope.INSTANCE);
}
I am new to Guice and trying to understand the scope of configure() method in your Module class. Currently below is my application structure. It works.
class MainClass {
public static void main(String[] args) {
Injector injector = createInjector(new MainModule(param1, param2, param3));
injector = injector.createChildInjector(injector.getInstance(FuncModule.class));
}
}
FuncModule.java
class FuncModule extends AbstractModule {
#Override
public void configure() {
// Register a AWS SWF Workflow Worker
// Register a AWS SWF Activity Worker
// Instantiate WorkflowFactory class
TempWorkflowClientExternalFactory obj = new TempWorkflowClientExternalFactoryImpl(<param1>, <param2>);
bind(TempWorkflowClientExternalFactory.class).annotatedWith(Names.named("temp1")).toInstance(obj);
}
}
I am trying to understand if my configure method is doing "too much". Is the intention/scope of configure method only limited to binding? If so, where would be best place to register the workers and instantiate the factory object?
You're right to wonder whether your configure method is the right place for this type of initialization; it's a matter of judgment. Guice does have this to say: Modules should be fast and side-effect free.
But the full power of the Java language comes at a cost: it's easy to do too much in a module. It's tempting to connect to a database connection or to start an HTTP server in your Guice module. Don't do this! Doing heavy-lifting in a module poses problems:
Modules start up, but they don't shut down. Should you open a database connection in your module, you won't have any hook to close it.
Modules should be tested. If a module opens a database as a course of execution, it becomes difficult to write unit tests for it.
Modules can be overridden. Guice modules support overrides, allowing a production service to be substituted with a lightweight or test one. When the production service is created as a part of module execution, such overrides are ineffective.
A few other factors to consider:
Your Guice module is still a Java class, and can and should adhere to the Single Responsibility Principle as much as with any other class. If the construction or configuration of your dependencies is more than a screenful or two, or is hard to describe in a sentence or two, it might be time to break up the module (see install) or extract the construction/configuration to its own method or class. You've given us a hint with your commented configure sections: Maybe it's time to extract methods or classes so the code is more self-describing.
Guice is just one dependency injection framework, and is designed to require very little Guice-specific code or patterns. With JSR330-compatible annotations (#Inject) and interfaces (Provider), you should be able to replicate or replace Guice's functionality manually—or with a different framework like Spring or Dagger (2)—without much trouble. Java Module instances, however, are unique to Guice; custom initialization code that lives in a Module will need to be refactored or rewritten if you ever want to use it in a non-Guice context. This may be a good reason to separate reusable initialization code from Guice modules in the first place.
Along similar lines, as the Guice wiki mentions, you should test any nontrivial logic in your classes. Guice Modules and their configure methods are hard to test without Guice; you may find it easier to test your external construction/configuration if it's in a separate class or method.
Any initialization you do in a Module's configure method happens when you call createInjector or createChildInjector, along with all other Modules in an unspecified order. This gives you very little granularity to set up logging, defer to a background thread, catch exceptions gracefully, or otherwise control when and how the initialization happens. By extracting third-party initializer code to a separate class or method, or a Provider or #Provides method, you give yourself more flexibility about when and how it is run.
All that said, Guice definitely allows for instance bindings, and it's very common to see simple and lightweight constructor calls, initializer calls, and other instance-preparing code in Modules. Creating a whole new class for a couple of lines of trivial initialization is probably overkill.
In short, leave in simple/short/safe initialization calls, but as soon as things get complicated/long/dangerous be ready to extract the creation or initialization to give yourself more control.
P.S. Separately, though there's nothing technically wrong with obtaining a Module instance from an Injector, be aware that it is not a common pattern. At best, this violates the rule-of-thumb that you don't have access to a functioning Injector at Module configure time; at worst, you may find it hard to reason about which Injector you're actually calling, and thus which bindings you have available to you. You can keep it, but use with caution, and consider keeping things explicit by passing parent-injector-sourced dependencies as Module constructor parameters.
/** Injected child module. Get this from a parent injector. */
public class BModule extends AbstractModule {
#Inject Injector injector; // You can always inject the Injector...
#Override public void configure() {
bind(B.class).to(BImpl.class);
}
#Provides C provideC(B b) {
return new C(b);
}
#Provides D provideD() {
return new D(injector.getInstance(B.class)); // but this won't work;
// injector is the parent,
// not the one with this module.
}
}
I just incurred in the infamous JavaEE CDI error under GlassFish server:
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001437 Normal scoped bean class ASController is not proxyable because the type is final or it contains a final method public final void ASController.selectPath(org.primefaces.event.NodeSelectEvent) - Managed Bean [class ASController] with qualifiers [#Default #Any #Named].
the error is quite explicative in the fact that he doesn't like final methods inside a CDI bean, however I can't grasp why.
At this link
http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e1429
they explain it is something to do with serialization but I can't see why serializing a class with a final method should be any harder than one with non final methods.
Well, there is several ways in which you can implement a proxy object. But since you expect the proxy to have the "same" type as the proxied bean, you'll have to use inheritance (or demand interfaces which you then could implement, but this would not be an approach where every POJO could be a bean for CDI).
That is, they internally extend from the class you want to inject, generate some proxy code around that and give you that sub class.
This proxy then is handling all the magic to make sure you always have a bean fitting your context (and this bean has all the members variable beans pointing to the just right beans).
So you are not really receiving the type of the bean you want to inject, but a proxy subclass of that bean. This does not work very well with final methods and classes and private constructors.
If the class is not final, the proxy can extend this class, it however cannot easily overwrite the final method of yours. This however may be needed (if e.g your bean is serialized, the proxy needs to deserialize it).
There is, more complicated ways, around that. One could inject this functionality by manipulating the byte code of your class via an agent (e.g removing the final modifiers, inject a default constructor, ...) and maybe even mix this with inheritance, but this is just not implemented, yet (and also non trivial to support over several JVM implementations).
From the linked resource a note indicating that this is planned for a future release:
Note
A future release of Weld will likely support a non-standard workaround
for this limitation, using non-portable JVM APIs:
Sun, IcedTea, Mac: Unsafe.allocateInstance() (The most efficient)
IBM, JRockit: ReflectionFactory.newConstructorForSerialization()
But we didn't get around to implementing this yet.
Container create proxy object for injected classes. So, container doesn't use your classes, but those classes extends. Java prohibit extends final classes, so you cannot use final classes in CDI.
I'm having some troubles understanding how Guice's singleton instantiations works. I've read the available documentation (here - http://code.google.com/p/google-guice/wiki/Scopes ), but I still can't figure out some things:
I've integrated Guice with Tomcat, and I've set up some bindings in a ServletModule:
bind(MyServlet.class).asEagerSingleton();
serve("myUrl").with(MyServlet.class);
serve("myOtherUrl").with(MyOtherServlet.class);
(where MyOtherServlet class has a #Singleton annotation above it)
My intention here was to have two servlets, where one is eagerly instantiated, while the other isn't. However it seems like the "serve... with..." line automatically instantiates servlets objects, even though that class is not bound as an eager singleton.
The link I attached above mentions difference between Guice running under Stage.Development and Stage.Production - however this still happened even when I explicitly used Stage.Development (which is the default one anyway).
Is there any way to avoid this?
(continues 1) Trying to ensure that MyServlet gets instantiated first even though all servlets instantiate eagerly now, I've modified the order of modules (and binding statements) when creating an Injector, so that the binding for MyServlet appears first. However, I found that it still gets instantiated later than some other bindings (of non-servlet classes), which were of the form:
bind(MyInterface.class).to(MyClass.class).asEagerSingleton()
even though those other bindings appeared later in the modules/bindings order.
I've looked into it, and found that Guice simply instantiates eager singletons which were bound by the form of "bind... to... asEagerSingleton()" before it does ones of "bind... asEagerSingleton()", and so I solved it by modifying the line:
bind(MyServlet.class).asEagerSingleton();
into:
bind(MyServletDummyInterface.class).to(MyServlet.class).asEagerSingleton()
and that actually worked. Still, I'd rather avoid having a dummy interface just to solve this, so I was wondering if anyone had a better solution for this..?
I have two Guice modules - one ServletModule and one AbstractModule.
The ServletModule configureServlets() has the following binding in it:
serve("aUrl").with(SomeServlet.class);
The AbstractModule's configure() has the following bindings:
bind(SomeImpl.class).asEagerSingleton();
bind(SomeInterface.class).to(SomeImpl.class).in(Singleton.class);
Additionally, The SomeServlet class has an injected field of type SomeInterface, and has a #Singleton annotation on top of the class.
Now, one would expect that upon creating an injector, the SomeImpl class will get instantiated, and the same instance will be injected into the SomeServlet instance. As mentioned before, servlets bounded with a "serve... with..." statement also seem to get eagerly instantiated, but either way there should still be only one SomeImpl object instantiated. Yet for some reason, I got two SomeImpl objects instantiated when doing this.
To get around it, I mixed the two lines in configure() a bit, and instead of the above I had there the following lines:
bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();
and then it worked fine, and I got only one instance of SomeImpl instantiated. I don't really get why the switch should matter - I can see how the latter way is "better", but I'd expect both to work correctly, so I'm just wondering if I'm getting something wrong here...
1) There is no way to avoid this, since Guice calls the init() method of all servlets on initialization of its own filter pipeline and thus constructs them all. If you really need such lazy initialization logic, you should place it into the servlet itself (or use a decoupled helper class, or... there are many ways, depending on your use case).
2) Generally said, the modules of Guice declare bindings, there are not designed to be bootstrap definitions with precise instantiation orders. If you need such a defined instantiation order, create the objects yourself in the desired order and bind them via bind(...).toInstance(...). If you need injection in the self constructed instances you may use requestInjection(...) (if field/method injection is sufficient, it's more cumbersome for constructor injection).
3) The scope of Guice applies to the binding key, not the binding value, Applying Scopes describes why only your second example is working as intended.
I have provider which should inject javax.mail.Session (provider looks it up in env. context of tomcat) as singleton. There is a problem when I use field injection somewhere in code:
java.lang.IllegalArgumentException: Cannot subclass final class class javax.mail.Session
Is there a way to go round this? Only clues that I've found point to Spring AOP/Proxies.
Thanks && regards
Look at this http://code.google.com/p/google-guice/wiki/AOP. It seems that there is some limitations:
Limitations
Behind the scenes, method interception is implemented by generating
bytecode at runtime. Guice dynamically creates a subclass that applies
interceptors by overriding methods. If you are on a platform that
doesn't support bytecode generation (such as Android), you should use
Guice without AOP support.
This approach imposes limits on what classes and methods can be
intercepted:
Classes must be public or package-private. Classes must be non-final
Methods must be public, package-private or protected Methods must be
non-final Instances must be created by Guice by an #Inject-annotated
or no-argument constructor