I'm wondering how I can bind a singleton to a parameter in a provider.
ie:
#Singleton
public class RunButtonController{
#Inject
public RunButtonController(EventBus eventbus){ ... }
public JComponent getView(){
return view;
}
...
}
public class UncaughtExceptionController{
#Inject
public UncaughtExceptionController(
EventBus eventBus, ...,
#Named(DefaultExceptionViewKey) JComponent defaultView)
{ ... }
...
}
public class GUIController{
//another consumer of RunButtonController, arguably the "main" consumer.
#inject
public GUIController(RunButtonController runButtonController,
UncaughtExceptionController uncaughtExceptionController, ...)
{ ... }
...
}
public class Bootstrapper{
public static void main(String[] args){
Injector injector = Guice.createInjector(new OptipModule());
GUIController controller = injector.getInstance(GUIController.class);
}
private static class OptipModule extends AbstractModule{
#Override
protected void configure() {
bind(EventBus.class).toInstance(new EventBus("OPTIPGlobalEventBus"));
bind(JFrame.class).to(GUIView.class);
}
#Provides #Named(DefaultExceptionViewKey)
public JComponent getFrom(RunButtonController runButtonController){
return runButtonController.getView();
}
}
}
Putting a breakpoint on my RunButtonController constructor, I can see it consistently getting instanced twice. I want it to only be instanced once, and I want
defaultExceptionViewProvider == runButtonController
to be true.
I've used Castle Windsor fairly extensively, but that's the only IOC container I've used, so I'm new to guice. I'm seeing remnants of visitor behavior all over the place, and guice's documentation makes it pretty clear that the defined behavior of a class (ie, instance once, use this instance, use this factory, ...) doesn't persist beyond the module it was configured for. I'd like to say that I saw it written that when you use an #Provides, guice creates a child module for you, so presumably what I need to do is tell this child #Provides-generated module that 'hey, this class is a singleton and I'm in the process of resolving it, so here it is! don't use your own!'
I think that I'm going about this framework the wrong way. I've been smashing down annotations and hitting debug, but perhaps what I really need to do is spend a few hours reading a good tutorial, unfortunately I cannot find one. The JavaDoc has examples, and the webpage publishes them, but they give you very little context and so, having read the article on #Assisted three times, I still don't understand it (perhalps that's what I should be using?) Bonus points for somebody who points in the direction of a particularly detailed blogger and a guice entry on his page.
Along those lines, and digressing enormously, I'm wondering what the ramifications are of me trying to pushing this 'hey your default notification area is this other guys view' into my IOC container. Is that maybe domain logic? I don't really want the UnhandledExceptionController to know that its view was provided by a RunButtonController, and similarly I don't want the RunButtonController to know its view is being used for anything other than being stamped out onto the view tree.
thanks for reading!
As posted, it looks like your code should work. That said, there are a few caveats that could cause singletons to coexist. Double-check the stack trace for each of the constructor calls.
It may be obvious, but you can create any number of instances outside of Guice's control, and Guice has no way of knowing those instances exist. Double check that nothing in your code calls the RunButtonController constructor manually.
Singleton behavior is enforced within any given injector. If you have two or more injectors in your application, they could each create their own instance of RunButtonController. A singleton declared in a parent injector would be visible to any child injectors, though.
Singletons work by key. If you were to remove the #Singleton annotation and add this:
bind(RunButtonController.class)
.annotatedWith(Names.named("Foo"))
.asEagerSingleton()
Then injecting RunButtonController would get you a new instance every time, but injecting #Named("Foo") RunButtonController would get you a separate singleton instance that would return the same every time. That probably doesn't apply to you, because the #Singleton is on the class itself, but it has bitten others before.
You don't seem to rely on inheritance, but remember that singleton annotations don't inherit from superclass to subclass.
Side note: #Provides methods don't work via child injectors, but private modules do (alluded to as "parent injectors" in the documentation). Internally, it's true that a separate internal module is responsible for calling those provider methods, but that doesn't really matter—singletons are shared between modules.
Regarding your digression about sharing views: You're doing fairly well already by injecting #Named(DefaultExceptionViewKey) JComponent instead of RunButtonController, but if you wanted to be even more implementation-agnostic, you could create an ExceptionHandlerComponent interface and code against that.
Related
I have got a mapper class which does a complex mapping of one pojo to another. I made the mapper class a bean and wired it to the service class. I could have made the mapper class a static class as well but I preferred a bean because I felt it better in a testability point of view, I can test the service and mappers independently by mocking the mappers. Indeed it’s also possible to mock the static classes but I will have to use powermock or something similar. Another reason to choose a bean is that for certain mappers I had to use interfaces so that I can choose the mapper implementation based on certain data conditions.
This implementation as a bean has triggered a controversy in my team with suggestions to implement it as a class with static map method or to create new mapper objects every time. And we are trying to figure out what is the best solution. Are there any industry standards being followed. Are there any trade offs with the beans approach? Can it have any impact on the performance of my application? imagine that I have got a hundred such mappers. Below is a simple Skelton of how my service and mappers looks like.
#Service
class CustomerService { #Autowired CustomerMapper customerMapper ...}
#Component
class CustomerMapper { #Autowired CustomerContactMapper ..
}
interface CustomerContactMapper {}
#Component
class InternalCustomerContactMapper implements CustomerContactMapper {}
#Component
class ExternalCuatomerContactMapper implements CustomerContactMapper {}
Well, there can be many opinions, if you want to follow conventions suggested by spring, then you did everything right.
Basically your point of testability is valid although its better to use constructor injection in this case because in the unit test you see exactly what is the required dependency:
class CustomerService {
private final CustomerMapper customerMapper;
public CustomerService(CustomerMapper customerMapper) {
this.customerMapper = customerMapper;
}
}
Side note: if you don't like the "boilerplate" of constructor, you can use Lombok that provides "AllArgsConstructor" anyway.
Now some points regarding the performance:
Spring initializes beans during the startup of the application. If these are simple-to-create classes (classes that do not load a lot of stuff upon creation, don't go to the db and so forth, just plain java objects) than it takes particles of second to initialize them all.
Later you have a regular function call (ok, if you work with interface then its a "virtual" call), but in general it doesn't affect the performance, in other words if the app works slow, the reason is likely to be anywhere else.
Regarding the alternative:
I didn't totally understand what does it mean "implement as a static class", however if you want to create a new mapper every time, this would mean that its not thread safe. In the current implementation the service is a singleton, so there won't be many instances of it, it will be only one instance per application context. However it can be called by many threads simultaneously.
So if you have to create many instances -> the mapper can't be used from many threads. This decision has nothing to do with Spring, its your code and your decision to make it non-thread safe (I'm not saying whether its good or bad, just stating the fact).
Now, if this is the case, then your solution is technically wrong. Spring supports this kind of usage via Provider class + there are other ways to inject prototype into singleton:
class CustomerService {
private final Provider<CustomerMapper> customerMapper;
You can read Here about this method
We are doing some refactoring and we have hit the wall here.
There are two service classes AService and BService doing different works have a circular dependency.
Earlier they were in a different libraries so there was no circular dependency existed. But now after refactoring we have moved them into a single library into a single package.
AService job is to persist some data into a NoSQL database for a separate use case.
BService job is completely different than AService job.
AService needs BService to GET some data.
BService needs AService to write some data to NoSQL Database and reads back.
How to fix the circular dependency issue with making each of them depends on each other. Any design pattern for such issues?
class AService {
#Autowired
private BService bService;
}
class BService {
#Autowired
private AService aService;
}
The real question is why your conception making A and B dependent of each over?
It could be that A and B represent the same concept, and may be merged.
It could also be that a part of your service A or B should be extracted in a new service C.
In that last case you need to know which method depends on which service, and which one could be extracted in a new service. Without having the context and the list of methods it's difficult to propose a solution.
In the case of indirect recursive methods, you may have to cut also some methods.
Side note: don't try to find a workaround to make it work with circular dependencies, it shows a conception problem, you have to do the refactoring.
Solution 1 (recommended):
the redesign of class responsibilities. Adhering to the Single Responsibility Principle and according to the class details you revealed, we can fix your class design by extracting at least one new class: the DatabaseConnector. This class encapsulates all database related operations (CRUD) and therefore lifts the circular dependency of the service classes (without changing the original conceptions of the classes).
// This is just a raw template to express the intention
class DatabaseConnector {
void createInDatabase(Object data) {
}
Object readFromDatabase(Object args) {
}
void updateInDatabase(Object data) {
}
void deleteFromDatabase(Object data) {
}
}
class AService {
#Autowired
private DatabaseConnector dbConnector;
}
class BService {
#Autowired
private DatabaseConnector dbConnector;
}
You can add more specialized methods to the DatabaseConnector to meet special requirements (e.g. readName(), readId(), etc).
Since it is likely that more classes will need to access the database in future, you already solved or prevented new circular dependencies today. Encapsulation solved potentially upcoming problems.
Solution 2: dependency inversion
interface IAService {
}
interface BService {
}
class AService implements IAService {
#Autowired
private IBService bService;
}
class BService implements IBService {
#Autowired
private IAService aService;
}
A circular dependency is always an indicator for bad class design. In most cases the origin is the violation of the Single Responsibility Principle (the S in SOLID). A wrong composition concept can also lead to this design error. What will always help, but not fix the conceptional flaws of class responsibilities, is the introduction of interfaces to invert all dependencies (the D in SOLID). Taking the SOLID Principles serious can safe a lot of time and work and will always lead to better code (although you introduced higher code complexity).
The Mediator Pattern can also help to lift circular dependencies by encapsulating the bidirectional interaction of two or more objects.
The downside of your current code is (besides the circular dependency), that whenever class A changes and also data persistence changes, you have to touch and modify class B. This changes can break class B which is using the same persistence operations. This is true for all cases where one class has shared responsibilities with another class. If there wasn't the shared code, both classes wouldn't know each other at all. In your special case, where the dependency is cyclic, you add this flaw to the other dependency direction as well: whenever B needs to adjust or extend how to read data then you have to modify class A, which might break A. If you are using unit tests, then you would have to refactor the tests of both classes too. This tight (and cyclic) coupling of A and B will lead to errors or bugs. Extending code has become dangerous. But the good news is that circular dependencies never compile (since the dependency resolution leads to infinite recursion).
The easiest way is to move the method that Service B uses out of Service A and into Service B OR into a completely different class.
The design indicates that you probably have too many methods in Service A which Service A does not actually use, but which are public methods that should really be static and in another Class entirely.
Try to put the autowired on setter instead:
#Autowired
public void setServiceB(ServiceB service){
this.serviceB = service;
}
I have inherited a Java web service project that is using Dagger 2. Based on my so far limited understanding of Dagger I am confused as to why every single class that is injected has the singleton annotation on it in the dagger module class's. If I was creating this application without dagger they would not all be singletons, is this something specific to dagger or have the previous developers simply misused Dagger?
[...] every single class that is injected has the singleton annotation [...] is this something specific to dagger [...]?
Nope. #Singleton is the only scope included with Dagger by default, but you can also create custom scopes, use #Reusable which may create multiple objects but will reuse them if possible, or no scope at all.
or have the previous developers simply misused Dagger?
If possible you should just ask them. If every object is a Singleton this looks like they did not invest a lot of thought in the setup and just copy-pasted declarations, at least this would be my assumption.
From the section about Reusable in the user guide:
Sometimes you want to limit the number of times an #Inject-constructed
class is instantiated or a #Provides method is called, but you don’t
need to guarantee that the exact same instance is used during the
lifetime of any particular component or subcomponent. This can be
useful in environments such as Android, where allocations can be
expensive.
Two main differences:
#Singleton annotated class is guaranted to give always the same instance. It is needed if we keep global state in it. #Reusable do not give any guarantee.
If any class requests the instance of #Singleton annotated class, double checking is performed (which is slow). In case of #Reusable, it isn't.
I'd use #Reusable scope for classes that are expensive to build (for example I'm using for Retrofit instance - but to be honest I've never made performance tests if it is worth to use this annotation at all).
On the other hand, I'm using #Singleton annotated class for the cache.
Also, if you have class which keeps encapsulated global state like this:
class StateWrapper {
final State state;
#Inject
StateWrapper(State state) {
this.state = state;
}
}
I mean the state is de facto kept in the State class, do not annotate StateWrapper as #Singleton, always annotate the smallest part: in this case the State class.
(This hint is taken from the video)
I'm using Dagger2 in a google appengine project and I have several servlets that make use of, what should be, a singleton instance of a given object (MyObject).
#Singleton
#Component(modules = {MyModule.class})
public interface MyComponent {
IMyObject object();
}
I then need DaggerMyComponent.create() to be a singleton too so that I can get the same IMyObject across all servlets. To do so, I added a
DaggerMyComponent INSTANCE = DaggerMyComponent.create()
to my MyComponent interface. However, that still allows create() to be called again by mistake and it doesn't necessarily look like a pretty solution to me.
Any ideas?
Thanks!
Unfortunately the docs seem to be saying that Dagger doesn't provide such a limitation so far as for version 2.0.1
In order to get the proper behavior associated with a scope
annotation, it is the caller's responsibility to instantiate new
component instances when appropriate. A Singleton component, for
instance, should only be instantiated once per application, while a
RequestScoped component should be instantiated once per request.
http://google.github.io/dagger/api/latest/dagger/Component.html
I'd like to introduce Guice for the use of an existing mid-sized project.
For my demands I need a custom scope (session is too big, while request to small for my project).
Imagine that I request guice to provide me an instance of Class A which has direct and indirect dependencies to many other classes (composition).
My custom provider is able to provide the instance of classes which are used as constructor arguments of all involved classes.
Question:
Do I really have to put an #Inject (and my custom scope) annotation on the constructors of all involved classes or is there a way that guice only requires these annotations on the top-level class which I request and that all further dependencies are resolved by "asking" my custom scope for a provider of the dependent types?
If this is true this would increase the effort of introducing Guice because I have to adjust more than 1000 classes. Any help and experiences during the introduction of guice is appreciated.
First of all, it's possible to use Guice without putting an #Inject annotation anywhere. Guice supports Provider bindings, #Provides methods and constructor bindings, all of which allow you to bind types however you choose. However, for its normal operation it requires #Inject annotations to serve as metadata telling it what dependencies a class requires and where it can inject them.
There reason for this is that otherwise, it cannot deterministically tell what it should inject and where. For example, classes may have multiple constructors and Guice needs some way of choosing one to inject that doesn't rely on any guessing. You could say "well, my classes only have one constructor so it shouldn't need #Inject on that", but what happens when someone adds a new constructor to a class? Then Guice no longer has its basis for deciding and the application breaks. Additionally, this all assumes that you're only doing constructor injection. While constructor injection is certainly the best choice in general, Guice allows injection of methods (and fields) as well, and the problem of needing to specify the injection points of a class explicitly is stronger there since most classes will have many methods that are not used for injection and at most a few that are.
In addition to #Inject's importance in telling Guice, it also serves as documentation of how a class is intended to be used--that the class is part of an application's dependency injection wired infrastructure. It also helps to be consistent in applying #Inject annotations across your classes, even if it wouldn't currently be absolutely necessary on some that just use a single constructor. I'd also note that you can use JSR-330's #javax.inject.Inject annotation in Guice 3.0 if a standard Java annotation is preferable to a Guice-specific one to you.
I'm not too clear on what you mean by asking the scope for a provider. Scopes generally do not create objects themselves; they control when to ask the unscoped provider of a dependency for a new instance and how to control the scope of that instance. Providers are part of how they operate, of course, but I'm not sure if that's what you mean. If you have some custom way of providing instances of objects, Provider bindings and #Provides methods are the way to go for that and don't require #Inject annotations on the classes themselves.
NO YOU DONT
GUICE does not ask you to inject every single object. GUICE will try and create only injected objects. So you can #Inject objects that you want to be injected.
On the scope bit - Scope essentially controls how your objects gets created by GUICE. When you write your own custom scope you can have a datastructure that controls the way objects are created. When you scope a class with your custom annotation, GUICE will call your scope method before creation with a Provider for that class. You can then decide if you want to create a new object or use an existing object from a datastructure (such as hashmap or something). If you want to use an existing one you get that and return the object, else you do a provider.get() and return.
Notice this
public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
return new Provider<T>() {
public T get() {
Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);
#SuppressWarnings("unchecked")
T current = (T) scopedObjects.get(key);
if (current == null && !scopedObjects.containsKey(key)) {
current = unscoped.get();
scopedObjects.put(key, current);
}
// what you return here is going to be injected ....
// in this scope object you can have a datastructure that holds all references
// and choose to return that instead depending on your logic and external
// dependencies such as session variable etc...
return current;
}
};
}
Here's a tutorial ...
http://code.google.com/p/google-guice/wiki/CustomScopes
At the most basic level, the #Inject annotation identifies the stuff guice will need to set for you. You can have guice inject into a field directly, into a method, or into a constructor. You must use the #Inject annotation every time you want guice to inject an object.
Here is a guice tutorial.