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.
Related
I am trying to apply ioc into a school project. I have an abstract class Application without any field
public abstract class Application {
abstract public void execute(ArrayList<String> args, OutputStream outputStream, InputStream inputStream) throws IOException;
}
And I will call the concrete class that extends Application by
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Application app = (Application)context.getBean(appName);
My questions are:
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
UPDATE
Here is the code snippet of the class where the instance of Application is needed.
String appName = argument.get(0);
Application app = ApplicationFactory.getApplication(appName);
ArrayList<String> appArgs
= new ArrayList<String>(argument.subList(1, argument.size()));
app.execute(appArgs, outputStream, inputStream);
Further questions:
in my code the class X will call the instance of Application by specifying a concrete application class name. In this case, it is still not possible for Spring to inject the dependency to Application, right? As what I need is a concrete class but not Application itself.
if Application does have fields but these fields are initialsed somewhere higher than X (X receives them as inputs and passes them to Application), can I use DI in this case?
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
No, its totally fine. Its true that you won't be able to "take advantage" of the automatic dependency injection mechanisms provided by spring (because obviously there are no dependencies in the class Application in your example), however spring can still:
Make sure that the Application as a singleton "obeys" the rule of being a single instance in the whole application context. For "manually" maintaining singletons you need to write code. Spring does it for you.
Manages the lifecycle of the object. Example, Spring has "postConstruct"/"preDestroy" methods that can can be run in the appropriate time and make example any custom code of the class Application.
If this class does some heavy-lifting (even without spring) than it can make sense to define it "lazy" so that the initialization of this instance will actually be done upon the first request to it.
Sometimes you/or spring itself will create a proxy of this class in runtime (for many different reasons, for example this aforementioned lazy functionality, but there are also other use cases). This is something that spring can do for you only if it manages the Application and not if its defined outside the spring.
Ok, you don't have dependencies in the application, This means that this Application class has some useful methods (at least on method, like public void foo() for
simplicity). But this in turn means that there is some class (lets call it X) that calls this method. So this class has an instance of Application as a dependency. So now the real question is who manages this class X. Probably it makes sense to manage it in Spring as well, and then you will benefit of the Dependency Injection mechanisms in this class X only because Application is also managed by Spring. In general Spring can inject dependencies only if these dependencies are managed by Spring.
I know, this last paragraph may sound vague given the use case you've presented, but you've got a point, for example in real application people make an initial bootstrapping in very certain places. Usually also people use spring boot that kind of encapsulates this kind of things for you.
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
So as you see, the concept of DI container goes far beyond of what the factory pattern has to offer. In short, factory pattern only specifies the way to create the objects. Spring on the other hand, not only creates the objects but also manages them.
First, I very strongly suggest that you use Spring Boot instead of manually manipulating Spring at a low level like this.
It's perfectly ordinary to use beans that don't have their own fields for settings, but this is usually so that other beans can have pluggable strategies or providers and you can define in your application setup which to use.
If your Application class doesn't need anything else, then there really is not much advantage to Spring. Most real-world programs get complicated soon, however, and that's where it becomes useful.
Finally, you should almost never pass ArrayList as a parameter; use List instead. In the code you showed, however, if you have String[] args, you couldn't say app.execute(Arrays.asList(args), System.out).
I have a Spring bean class which requests dependencies to be injected. However, in my class, I am manually wiring different dependencies to the same private class variable. What happens in this scenario? Which injection takes precedent?
Details:
I have created a Spring bean class called BadmintonCoach.
It relies on an IfortuneService helper. IfortuneService is an interface with TWO different implementations. The two implementations are:
FortuneService_RESTful
FortuneService_Random
In my badmintonCoach class, I have created a private variable to receive the injection from Spring:
private IFortuneService theFortuneService
That is to say, I am manually wiring up the the injected dependency to this private member, theFortuneService
I am injecting these iFortuneService dependencies using method injection.
BUT here is the problem: I have TWO methods, both of which request an injection from Spring of the type iFortuneService. One method requests one implementation (FortuneService_RESTful) and the other method requests a bean of the other implementation (FortuneService_Random).
Both of these methods set this.theFortuneService equal to its respective requested helper. So what I have within my BadmintonCoach class is:
private IFortuneService theFortuneService
#Autowired
#Qualifier("fortuneService_Random")
public void randomMethod_ONE(IFortuneService theFortuneService) {
System.out.println("Code inside randomMethod_ONE!");
this.theFortuneService = theFortuneService;
}
#Autowired
#Qualifier("fortuneService_RESTful")
public void randomMethod_TWO(IFortuneService theFortuneService) {
System.out.println("Code inside randomMethod_TWO!");
this.theFortuneService = theFortuneService;
}
My question then, is:
Which of the two wirings wins out? Why? How does Spring decide the ORDER of its injections? What determines the order of the injections? Is it random? Is it injected in alphabetic order of the method names? Is there an order of injection between constructor, setter, field and method injections?
What am I seeing when I run my program? I am seeing the injection of fortuneService_RESTful win out, but it is unclear to me whether this is by chance or by design from within Spring's logic.
Here is another thought:
What if, instead of requesting different implementations of the IFortuneService interface, the two methods above asked for the same bean but that bean was prototyped? Clearly, there would be a new incarnation created for each request and there would only be one helper class assigned to my BadmintonCoach class. But which incarnation would win out?
I can provide the whole of my code if it will make my question clearer.
If you are wondering WHY I have written conflicting code? It is plain and simple curiosity to try and understand how Spring works behind the scenes.
OK folks, it has taken a day for me to see this but I can confirm that what happens here is indeed random!
Yesterday, I was exclusively seeing method_ONE win out. Today, I am seeing method_TWO win out. I can therefore conclude that the order of injections by Spring is indeed random!
Thomas Klager had provided a suggestion in the comments above which may explain this phenomenon:
One obvious reason [for this] is that using annotation based injections, spring
needs to list the methods of a class using Class.getDeclaredMethods()
or Class.getMethods(). Neither of these methods return the methods in
any particular order.
I still find it a mystery how execution of the same logic by Spring (ie: Class.getDeclaredMethods() or Class.getMethods()) can yield random results like this.
It is very important to be aware of this limitation! When writing code, you may find yourself wanting to use the services of injected dependencies which in turn depend on the services other injected dependencies. It is clear from this experiment that this could potentially be dangerous and therefore you should not layer your wiring in this manner. That is to say, your wiring should always be single tiered if it spans multiple methods, otherwise, you risk spurious output from your program. An illustration of this danger can be seen in Slim's answer in this link.
I have a working call to a web service; we implement the logic to call the web service with a Spring bean configured with annotation:
#ManagedResource(objectName = "bean:name=XServiceMBean")
#Service("xService")
public class XServiceImpl implements XService
{
// working code here
}
For testing purposes, I would like to extend this class and inject the subclass instead of this one, so I made:
#ManagedResource(objectName = "bean:name=XServiceMBean")
#Service("xService")
public class XServiceImplTest extends XServiceImpl
{
// working code here
}
and commented out the two annotation lines from the superclass.
Spring doesn't like it. When I run, I get:
Error creating bean with name 'xService':Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'xService' must be of type [com.hsc.correspondence.rules.XService], but was actually of type [com.hsc.correspondence.rules.impl.XServiceImplTest]
I tried it again putting an explicit "implements XService on my subclass, with the same result.
Am I doing something illegal in Spring? The original XServiceImpl has a number of #Resource annotations in it; I didn't think that would matter, I expected them to get injected just like they did before.
Is there a way to do what I want to do, which is have a test class with absolute minimized changes to the original? (I would consider configuring in XML except I don't make those decisions in the project I'm on, but I didn't think it would matter to what I'm trying to do.
additional puzzlement: the error message says "Bean named 'xService' must be of type ...XService, but was actually of type XServiceImplTest". But XServiceImplTest implements XService, just like XServiceImpl does.
additional puzzlement #2: I copied the entire XServiceImpl to the class XServiceImplTest, commented out the annotations from XServiceImpl, and cleaned and rebuilt and ran. Got the same result. Now the only difference between the two classes is their class names. It gets stranger and stranger. Can anyone suggest why Spring might care what the class name is?
I see three possible causes for this:
Your code doesn't look like the one you are showing, and the inheritance hierarchy isn't there. (Since you say you directly added the interface this is unlikely, but you might want to double check your imports)
There is old compiled classes on the classpath. If there is an old compiled version lying around of XServiceImplTest this might get picked up. Try a clean of all class/target folders.
You are running in some kind of classloader issue, and the interface gets loaded by a different classloader than the test implementation. Put a breakpoint on the line where the execption is thrown and inspect the classloaders of the various classes involved.
You can do that by doing x.getClass().getClassLoader() on any instance of interest. In a plain vanilla application this will return the same instance for all x. In OSGI applications and web application you might get different ClassLoaders. The type of the ClassLoader and their parent relation ship should give some hint about what is going on.
They can't have the same name. You are calling "xService" to both classes.
You can give the subclass a diferent name "xServiceTest" for instance and inject that using #Qualifier.
Other thing, I'm not 100% sure but I think that you could have problems with this kind of inheritance. If you have, just create an abstract class that has all the common implementation and then create 2 sub-classes, the service and the test.
Hope this helps.
[UPDATE]
Can anyone suggest why Spring might care what the class name is?
You can check in your configuration for weird context:component-scan entries. Check if you have defined something like this:
<context:component-scan resource-pattern="<path>/*Impl.class" ...>
and/or some specific include/exclude criterias.
This question is a continuation of Using guice for a framework with injected classes, proper way to initialize?, which I've tried to implement, and also tried other ways to get around the issue, but nothing has worked so far.
The main issue is this. I have an InterfaceA and InterfaceB that are exposed in different parts of the API. There are two classes that implement both of these interfaces, TestClass and RealClass, so that depending on whether I'm testing or doing something else, I can do the following:
bind(InterfaceA.class).to(TestClass.class);
bind(InterfaceB.class).to(TestClass.class);
or, for production:
bind(InterfaceA.class).to(RealClass.class);
bind(InterfaceB.class).to(RealClass.class);
I have two requirements for using these classes:
I need the same instance of TestClass or RealClass to be bound to all injections of InterfaceA and InterfaceB; so, like a singleton pattern, except that:
The singleton is only for a specific scope or child injector, many of which are created during the execution of the program.
The default no-scope approach causes multiple instances of RealClass/TestClass to be created for each interface injection. I don't want that, so I've tried implementing this with scopes, child injectors, and other methods. Nothing has worked:
Child injector approach: I create a new injector and try to bind the TestClass or RealClass to a singleton instance in that injector. The problem is, whether TestClass or RealClass is being used is configured in the parent injector, and since it's a singleton, it's already instantiated (unless in Stage.DEVELOPMENT). There's no way to bind InterfaceA to TestClass, in the parent injector, for example, and then re-bind it as a singleton in the child injector.
Scope approach: I create a custom scope and annotate TestClass and RealClass. Then, I enter and exit this scope to get single instances in that scope. The problem is that my code is multithreaded and having the scope change from one thread affects what the global injector can see and mucks up creating other instances.
Combined child injector and scope approach. I tried creating a child injector for each use of this custom scope, but then binding RealClass in the parent fails with
No scope is bound to name.package.WhateverScope.
because it seems to insist that the WhateverScope is available all the time, not just in the child injector.
All these problems seem to be due to the fact that I need to be able to configure whether to use TestClass or RealClass in the parent, but then to be able to instantiate them later, as a singleton, for a specific group of objects. I'm pulling my hair out over how to get this done!
By the way, the documentation for Guice scopes is horrible and almost impossible to understand. This article is the only one that has gotten me anywhere:
Apologies for a somewhat-breakthrough less than an hour after posting.
I seem to have been able to fix this by somewhat abusing the thread-local scope implementation provided at http://code.google.com/p/google-guice/wiki/CustomScopes. It seems to be a somewhat clean way to solve this problem without using child injectors. I'm not sure if it's 'proper', though. I'll still accept other answers.
Here's what I did. First, I create one instance of the scope, bind it to the appropriate annotation, and make it available in the injector:
ThreadLocalScope scope = new ThreadLocalScope();
bindScope(ExperimentScoped.class, scope);
bind(ThreadLocalScope.class).toInstance(scope);
Then, as the documentation says, I need to bind a fake provider for every type of key that would be seeded in the scope:
bind(SomeKey.class)
.toProvider(ThreadLocalScope.<SomeKey>seededKeyProvider())
.in(ExperimentScoped.class);
bind(SomeOtherKey.class)
.toProvider(ThreadLocalScope.<SomeOtherKey>seededKeyProvider())
.in(ExperimentScoped.class);
I may also have some other scope-able objects that I want to be distinct within each scope, so I bind those too. These are the TestClass and RealClass above. There may be also SomeScopedClass that was annotated with the #ExperimentScoped:
bind(InterfaceA.class).to(TestClass.class).in(ExperimentScoped.class);
bind(InterfaceB.class).to(TestClass.class).in(ExperimentScoped.class);
bind(SomeInterface.class).to(SomeScopedClass.class);
Finally, I can use the scope to create distinct sets of interdependent objects, in parallel from different threads. Each thread can do something like the following, even though they are using the same injector:
ThreadLocalScope scope = injector.getInstance(ThreadLocalScope.class);
scope.enter();
try {
// Seed the seed-able keys
scope.seed(SomeKey.class, keyInstance);
scope.seed(SomeOtherKey.class, otherKeyInstance);
SomeScopedClass instance = injector.getInstance(SomeScopedClass.class);
// Hooray! instance was injected with the seeds and created just for this scope!
}
finally {
scope.exit(); // Throws away the scope and referenced objects.
}
In my case, I can discard the scope completely because I don't care about keeping track of the set of objects in the scope once they're wired up properly. But it probably wouldn't work if I wanted to come back to this scope later and inject some more objects.
Hope this helped someone. The Guice scoping documentation is terrible!
We have two singleton objects (declared via in(Scopes.SINGLETON)) in Guice that each uses the other in its constructor. Guice's way to implement this is with proxies - it initializes the object at first with a proxy to the other object, and only when that object is needed it is resolved.
When running this code from several threads, we get the following exception:
java.lang.IllegalStateException: This is a proxy used to support
circular references involving constructors. The object we're proxying is not
constructed yet. Please wait until after injection has completed to use this
object.
at
com.google.inject.internal.ConstructionContext$DelegatingInvocationHandler.invoke(ConstructionContext.java:100)
I assume this is a bug in Guice, because we aren't doing anything out of the ordinary. One workaround we found is initializing the singletons early using .asEagerSingleton(), but this is not very convenient, for testing for example.
Is this a known issue? Reported an issue with Google Guice, reproduces with a standalone test.
Any other suggestions/workaround?
Did you try injecting a Provider<T> in each constructor instead of the actual instances?
If you don't need the other instance in the code of constructor, then just store the Provider to a final field, and use this field later on (by calling get()).