I have some webapp UI components that are currently generated in loops - a necessity because they are representing dynamic one-to-many associations. The hierarchy is 3 levels deep (tabs->tables->rows/columns). I'm using spring's getBean(...) to generate them so that as the codebase is enhanced we can #Autowire service dependencies without changing constructors all the way up the hierarchy.
The code currently works like this...
class Tab {
public void postConstruct(){
for(int i=0;i<count;i++) {
context.getBean(Table.class);
}
}
}
class Table {
public void postConstruct(){
for(int i=0;i<count;i++) {
context.getBean(Column.class);
}
}
}
class Column {
public void postConstruct(){
...
}
}
I understand the calls to getBean() are frowned upon, and I also have concerns about the performance of getBean(), but Im not sure I have much choice here. There is almost certainly a performance impact, and I don't want to head down this road if it's going to be an issue.
I'm wondering if Im missing a better alternative that still uses spring, or should I revert to using constructors and manually pass all dependencies.
Related
Studying about dependency injection I found some approaches that suggests to inject everything and other saying that it's not necessary to do so.
In my current project, my rule of thumb regarding Dependency Injection is "if the class was created by me, I make it injectable". In other words only classes like SimpleDateFormat, ArrayList, HashMap are newables in my project. My intent doing this approach is that I can #Inject any class anywhere once calling Injector.getApplicationComponent().inject(this) in the Activity. Basically all my classes have a non-args constructor with #Inject.
I was primary using DI because I thought it will improve the performance and memory usage once the new operator is used exclusively by the Dagger generated classes. But I read a post from Dagger 1 developer saying that DI does not have impact on performance and the usage is basically to reduce boilerplate.
The first question is:
Dagger 2 does not any performance advantage in Android application?
My project is running without problems and I think the approach of "inject everything" helps organizing better, despite some drawbacks.
An example of usage of this approach is the following class:
public class TimelineEntryAdapter {
#Inject
Provider<TwitterEntry> mTwitterProvider;
#Inject
Provider<InstagramEntry> mInstagramProvider;
#Inject
Provider<FacebookEntry> mFacebookProvider;
#Inject
TimelineEntryComparator mComparator;
#Inject
public TimelineEntryAdapter() {
}
The second question is:
Is it a bad practice to inject everything in Android?
If the answer for the second question is "No", there is a better way to handle the non-args constructor to create classes? Because when I create an non-args constructor with #Inject annotation and a class need some parameters to work with, I must use setters:
public class SavelArtist {
private MusicBrainzArtist mMusicBrainzArtist;
private DiscogsArtist mDiscogsArtist;
private List<SavelTweet> mTweetList;
private SpotifyArtist mSpotifyArtist;
private List<SavelInstagram> mInstaTimeline;
private List<SavelFacebook> mFacebookTimeline;
private List<SavelRelease> mReleases;
#Inject
Provider<SavelRelease> mReleaseProvider;
#Inject
public SavelArtist() {
}
public void setMusicBrainzArtist(MusicBrainzArtist mbArtist) {
mMusicBrainzArtist = mbArtist;
}
public void setDiscogsArtist(DiscogsArtist discogsArtist) {
mDiscogsArtist = discogsArtist;
}
public void setTweetList(List<SavelTweet> tweetList) {
mTweetList = tweetList;
}
public void setSpotifyArtist(SpotifyArtist spotifyArtist) {
mSpotifyArtist = spotifyArtist;
}
public void setInstaTimeline(List<SavelInstagram> instaTimeline) {
mInstaTimeline = instaTimeline;
}
public void setFacebookTimeline(List<SavelFacebook> fbTimeline) {
mFacebookTimeline = fbTimeline;
}
All the parameters could be set on the constructor, once all are get at the same time in the flow.
Studying about dependency injection I found some approaches that suggests to inject everything and other saying that it's not necessary to do so.
The froger_mcs blog entry you quote doesn't advocate injecting everything. It quite clearly states:
The purpose of this post is to show what we can do, not what we should do.
And it goes on to state a disadvantage of injecting everything:
If you want to use Dagger 2 for almost everything in your project you will quickly see that big piece of 64k methods count limit is used by generated code for injections.
Now, on to your questions:
Dagger 2 does not any performance advantage in Android application?
While Dagger 2 offers a performance advantage over other reflection-based DI frameworks (such as Guice) it doesn't claim to offer any performance advantage over manually constructing your object graphs by calling constructors. You can inspect the generated classes yourself to see that these indeed still eventually call constructors.
Is it a bad practice to inject everything in Android?
Well let's take the following very common Android code:
Intent nextActivity = new Intent(this, NextActivity.class);
startActivity(nextActivity);
Should we extract an IntentFactory and inject this using Dagger 2 merely to avoid the new keyword here? At this point, it is easy to approach pedantry. The advice in the other answer you quoted about the difference between injectables and newables is more flexible and elegant.
Moving on to your next question:
If the answer for the second question is "No", there is a better way to handle the non-args constructor to create classes? Because when I create an non-args constructor with #Inject annotation and a class need some parameters to work with, I must use setters:
Using setters is the wrong approach for parameters. You should distinguish dependencies and parameters. Dependencies normally have the same lifecycle as the object itself. During the lifetime of the object, the methods exposed for that object may be called with different parameters.
I'm not a professional at dependency-management but I use it in my company so here's how I see it.
Inject everything is basically good. I make everything that is used somewhere else ( other modules, classes, packages ) injectable and only static things ( static classes with hidden constructor ), things that get only used internally non injectable.
What's the advantage of it?
Well The dependency system will take care of getting the instance and to discard it. It will clean up automatically. Also using scopes on the classes will enable you to make a class that always has only one instance in the whole application ( multiple threads access it) or make it reusable ( every thread that needs it get's an own instance ).
Also I think you could clean up your classes like this:
#Reusable (Maybe a good Idea?)
public class SavelArtist {
private MusicBrainzArtist mMusicBrainzArtist;
private DiscogsArtist mDiscogsArtist;
private List<SavelTweet> mTweetList;
private SpotifyArtist mSpotifyArtist;
private List<SavelInstagram> mInstaTimeline;
private List<SavelFacebook> mFacebookTimeline;
private List<SavelRelease> mReleases;
private Provider<SavelRelease> mReleaseProvider;
public SavelArtist() {
}
#Inject
public void init(Provider<SavelRelease> mReleaseProvider) {
this.mReleaseProvider = mReleaseProvider;
}
Think about always declaring the scope of the class. Is it a Singleton? Will it be reusable? This little detail can save you, once the application get's complex and big.
The advantage of using the method init to declare all injected variables is to have a clean looking code which is easy maintainable since everything injected is at this one location. But that's actually preference :)
I'm trying to migrate a project from Spring and starting to play with Dagger 2 by following a sample GitHub repo.
In Spring I can use an annotation at the class level to expose all of the methods of a class, including void methods. I want to do this in Dagger 2 i.e., I want to 'provide' a void method.
In the code example below maybe I should move the printRandomUUID method to the Printer interface. However, I'm doing this little exercise with the goal of migrating a classical Spring #Component or #Service.
What is the correct approach? Is it possible to provide a void method at component or module level?
public class Main {
interface Printer {
void printMsg(String msg);
}
static class ConsolePrinter implements Printer {
#Override
public void printMsg(String msg) {
System.out.println(msg);
}
}
#Singleton
#Component(modules = ConsoleModule.class)
interface HelloWorldApp {
Printer getPrinter();
//this doesn't compile -> java.lang.IllegalArgumentException: not a valid component method:
void printRandomUUID();
}
#Module
static class ConsoleModule {
#Provides
Printer providePrinter() {
return new ConsolePrinter();
}
//this doesn't compile -> #Provides methods must return a value (not void)
#Provides
void printRandomUUID() {
System.out.println(UUID.randomUUID().toString());
}
}
public static void main(String[] args) {
HelloWorldApp app = DaggerMain_HelloWorldApp.create();
app.getPrinter().printMsg("Hello");
System.out.println("-");
//app.printRandomUUID();//here i want a void method to be consumed, from the component.
}
}
This isn't possible (yet). Unlike with Spring, Dagger is only configured by inspecting the Component interface and Modules. This means that Dagger #Component methods have to match the format of the methods from the #Component documentation, and there's currently no way of providing arbitrary code or methods that delegate to other instances.
That's not to say Components can't have void methods: They can, but they're required to be one-parameter methods that inject #Inject-annotated methods and fields in externally-created instances. These are known as members-injection methods, and instead of void they can also return the type they accept for ease of chaining.
From a different standpoint, I would argue that combining arbitrary business logic with your Dagger-created component is a bad idea for reasons of simplicity and correctness:
To do so may be violating SRP or separation-of-concerns: One of the stated advantages of dependency injection is the separation of object-creation logic from other business logic. Allowing the addition of a business method on an object-creation Component should feel as improper as the use of new in a business component. (Whether or not every single object should be provided through a DI graph is a contentious topic for another day.)
If you hold to best practices and avoid side-effects and other "heavy lifting" in constructors/factories/providers, then you should be able to reason cleanly about what can and can't happen from within a Component method. Allowing for arbitrary methods--particularly void methods--on a Component would be antithetical to that practice.
If your application uses separate granular libraries instead of a monolithic compilation step, then consuming a Component from within its own object graph may make it hard to build without introducing a dependency cycle. Of course, Dagger does allows for the injection of a component within its own graph, but doing so recklessly may cause cycle problems later.
Similar use-cases are so easy to represent using existing structures--making a Runnable available through the graph as Louis Wasserman commented, or injecting a similar single-purpose object to hold the method--that keeping arbitrary implementations off of the Component seems to result in no big loss of functionality or readability. At worst, you need one extra method call to get to a class you define.
If I were migrating as you are, I would make a class adjacent to HelloWorldApp called HelloWorldMethods, and shift all of the methods I would put on HelloWorldApp onto that instead. If this is a common pattern in your Spring migration, you might even define a local convention for it (FooComponent comes with FooMethods or FooUtil, for instance). Finally, if you wanted to hide the Dagger implementation details (as in an external API) you could also write your own class that wraps and consumes your Component, delegating important methods to the inner Component and providing whichever arbitrary implementations you need.
Which dependency should locate in a method signature as a param and which should not? Since we have IoC container like spring, most of the dependencies could get injected through it.
For java.util.concurrent.Executor:
public interface Executor {
void execute(Runnable command);
}
The interface could be
public interface Executor {
void execute();
}
Another case, in a traditional web application, a counter may be written like this
public interface CounterManager {
int query(User user);//user is a runtime information
}
Since spring offers request scope, User could be injected either.
public interface Counter {
int query();//get user through Injected
}
Is there some principle or best practice to make the choice? Thanks!
Is there some principle or best practice to make the choice? Thanks!
You can use "Coding complexity rule" as a guidance. Everything that lowers code complexity in both short-term and a long-term way is good. Everything that raises it is bad.
If you start injecting everything with a use of DI container, you will end up with a DI settings file of Merriam-Webster Dictionary in size.
If something is so plain simple, that can be just passed as a parameter to a method, why to complicate things with a DI container?
I'm currently trying to improve the testability of a legacy system, written in Java. The most present problem is the presence of “inner” dependencies which cannot be mocked out. The solution to this is pretty simple: Introduce dependency injection.
Unfortunately the code base is pretty large, so it would be a huge effort to introduce dependency injection throughout the whole application, up to the “bootstrapping”. For each class I want to test, I would have to change another hundred (maybe I’m exaggerating a bit here, but it definitely would be a lot) classes, which depend on the changed component.
Now to my question: Would it be ok, to use a two constructors, a default constructor which initialize the instance fields with default values and another one to allow the injection of dependencies? Are there any disadvantages using this approach? It would allow dependency injection for future uses but still doesn’t require the existing code to change (despite the class under test).
Current code (“inner” dependencies):
public class ClassUnderTest {
private ICollaborator collab = new Collaborator();
public void methodToTest() {
//do something
collab.doComplexWork();
//do something
}
}
With default / di constructor:
public class ClassUnderTest {
private ICollaborator collab;
public ClassUnderTest() {
collab = new Collaborator();
}
public ClassUnderTest(ICollaborator collab) {
this.collab = collab;
}
public void methodToTest() {
//do something
collab.doComplexWork();
//do something
}
}
This is absolutely fine, I do this occasionally also, especially with service-style classes where a default constructor is necessary because of legacy code or framework constraints.
By using two constructors, you're clearly separating the default collaborator objects while still allowing tests to inject mocks. You can reinforce the intent by making the second constructor package-protected, and keeping the unit test in the same package.
It's not as good a pattern as full-blown dependency injection, but that's not always an option.
I think this is perfectly OK. I would write the default-constructor in terms of the parametrized one, but that is probably a question of style and preference.
What I would be more cautious about is adding a setCollaborator()-function, because this radically changes the contract (and assumptions) for ClassUnderTest, which will lead to strange error-scenarios if called from code written by someone who doesn't know the history, haven't read the docs properly (or maybe there isn't any docs at all...)
I first thought about using ITDs to define the private static final Logger logger = ... for some unrelated cases, but it doesn't look enough like an obvious improvement to use that as a demonstration example.
Is there some standard/suggested example of ITD usage, which people should use for teaching purposes?
I'd like to add another example to Adam's answer.
Using aspects is a way to improve modularization of your software, as well as OOP is, except that OOP is applied "vertically", while AOP is applied "horizontally".
So, while advice can be used to modify "horizontally" the behavior of all methods responding to some criteria, aften code in advice will need also some data, and ITD makes it possible to add that fields "horizontally" while at the same time contain in a single compilation unit (the aspect) related data and code.
Since you are adding data via ITD fields, you'll probably also want to offer some method to manipulate those fields, like a setter/getter.
I tried to rephrase it a few times, I hope it's easy to understand.
To give you an example, suppose you have a graphical editing program, where the user can create, delete and display a number of Shapes (pretty canonical eh? :D ).
Shapes have a lot of data, for example they have a color, coordinates etc.. which correctly belong to the class itself. However, since this is a web 3.0 application, you want users to be able to cooperate on a single drawing, which means each shape must know when it is changed, if it has been communicated to other users that the shape is changed, wether it is locked by some user that is actually dragging it etc..
You can do it in simple OOP, implementing relevant parts in Shape or whatever your root class is, but you will the pollute all your setters with calls like "this.setDirty(true)" or similar stuff.
Instead, you decide to go AOP and implement it in an aspect. In this case, you can easily add an advice after all setters, but you'll also need to store a "dirty" boolean, or even a list of properties that changed if you want to optimize your network protocol sending only deltas of changes.
You could implement it like
public aspect ShapesAreDirtyThings {
private boolean Shape.dirty;
after(Shape s) : execution(* Shape+.set*(..)) {
s.dirty = true;
// Set some other global field, start a thread to communicate
// to other users about the change, whatever ..
}
public boolean Shape.isDirty() {
return s.dirty;
}
public boolean Shape.findDirtyChildren() { // whatever
}
This is nothing you cannot do with common AOP, is simply a matter of encapsulating in a single compilation unit advice, data needed by that advice, and methods that will eventually operate on that data.
Java does not support multiple inheritance or mixin. But with ITD's you can make Scala like Traits or Ruby like Mixins.
Here is an example taking advantage of JPA and Spring's Configurable:
Interface:
package com.evocatus.aop;
public interface DomainNotify {
public void postPersist();
public void postUpdate();
public void postRemove();
}
AspectJ ITD:
package com.evocatus.aop;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.springframework.beans.factory.annotation.Autowired;
import com.evocatus.service.DomainNotifyService;
privileged aspect DomainNotifyAdvice {
#JsonIgnore
#Transient
#Autowired
transient DomainNotifyService DomainNotify.domainNotifyService;
#PostPersist
public void DomainNotify.postPersist() {
this.domainNotifyService.publishSave(this);
}
#PostUpdate
public void DomainNotify.postUpdate() {
this.domainNotifyService.publishUpdate(this);
}
#PostRemove
public void DomainNotify.postRemove() {
this.domainNotifyService.publishRemove(this);
}
}
Now any class that implements DomainNotify will get the ITD methods weaved in.
#Entity
#Configurable
public class MyJPAObject implements DomainNotify {
}
Take a look at Spring ROO. It is a rapid dev. env using Spring. I see it as a Ruby on Rails but in java with Spring ;-)
It use ITD a lot to generate getter, setter, toString etc... based on the attributes you define when you create your Class.
Spring Roo