I am trying to understand basics of Spring dependency injection and auto wiring. All text books say, that the main advantage of dependency injection is that you can modify the application without touching the java code, by just modifying the XML.
But, when you use annotations, this purpose is defeated! Then what is the big deal? Why not just instantiate it than having additional code for injection?
In earlier versions of Spring, all injection had to be done using XML. With large projects, the XML itself became very large and difficult/cumbersome to maintain. Changes to dependencies in code required corresponding changes in the XML. Auto-wiring was added as a convenience to reduce the size of the XML.
However, auto-wiring does not degrade dependency injection, because XML can be used to override it. This gives the original flexibility of the XML configuration with the convenience of allowing Spring to default the common case where there is only one possible bean in the context that implements the interface.
Your question seems to be asking why we want dependency injection at all: "Why not just instantiate it than having additional code for injection?". One of the most common uses of dependency injection is in unit testing: A test program injects a test version of a dependency into the object under test to break further dependencies. For example, if service class A makes a call to service class B, and B relies on DB objects, other services, file systems, etc., then testing A becomes very difficult if A instantiates B directly because you need to make sure all of B's dependencies are met. If A is coded to an interface iB instead of the Class B, then the unit test code can inject a instance of a test class that implements iB and responds to method calls without any further dependencies.
I believe that there are many developers that believes that if you want to build long lasting maintainable code you should abide by the SOLID-principles.
The D in SOLID stands for Dependency inversion principle which basically means Dependency Injection. So, Dependency Injection is a good thing if you want to keep your code clean and separate object creation from the actual business code. Furthermore, DI makes your code more testable according to me.
You are right that annotations such as #Autowired is intrusive on your code but you do not have to change the logic or anything, simply annotate the methods.
Another way of dealing with dependency injection is also to use Java Configuration via #Configuration and the #Bean annotations (see the Spring docs). If you are really concerned with adding #Autowired to your code, Java Configuration is less intrusive.
This SO-question gives a good overview of why DI is important and good. One quote from that post is:
Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing, since it allows dependencies to be mocked or stubbed out.
having control over the service instances and loose coupling, you can inject any class that implements the requested interface in the annotation.
Related
Are there some benefits to use expression delegate over java class in camunda
Only thing I can imagine using expression delegates over Java classes is that, whenever my custom code class required to load from spring beans using dependency injection, specially where you want to control the lifecycle of delegation instance by your application, not Camunda runtime engine.
In simple words, by using expression delegates, we can initialize the delegate class as we want using spring DI without letting Camunda engine to initialize it. And take all advantages of DI.
The scenario is that we want to load our delegation class from spring beans, where it requires runtime dependencies to be injected before our delegation code runs. So, we can use spring beans to initialize other object dependencies and create a bean referencing the delegation class injecting other initialized beans. For example,
<serviceTask id="paymentTask" camunda:delegateExpression="${myPaymentBean}" />
In above, myPaymentBean is resolved from spring and it will be an instance of JavaDelegate which has already initialized with required dependencies through dependency injection (DI). We used DI, because our business logics needs to be tested thoroughly before going into production and easier to write automated tests on top of them.
If you use Java classes, then the instance initialization part will be done by the camunda engine, and there is a restriction that there must be a public default constructor. This is very limited since most of practical applications have dependencies and must be already initialized before the code. Either you have to make your dependencies as singletons (which is I never recommend) or use factories to create instances before code (which is inefficient and harder to test).
Hope this clarifies your question.
I'm still learning about the Spring Framework and I'm trying to really get a good understanding of when and how to use Dependency Injection
Should all dependencies be managed via Interfaces?
Use interfaces for dependencies that expose an API of some sort and that have an implementation that may need to be swapped out (e.g. using mocks in unit tests). One common case is the DAO (data access object), which in Spring Data refers to as a Repository, which ties your data model to a persistence layer. Another common case is a Service which exposes operations on your domain model. Typically a Service will depend on the data access layer, so to unit test the service you will mock the DAO/repository. Another example is a third-party service; these are often only used by production systems, but must be simulated in development and testing environments. In this case, an interface is far superior to, say, embedding boolean flags in your code and hoping you don't have any logic errors.
The key thing to remember about managing dependencies is actually managing your use of the new keyword. Any time you use new, you are creating a dependency on an implementation. The goal of dependency injection is to separate how you use things you depend on with how you get them. You can depend on either an interface or a class, for a simple, obvious reason: Java supports subclassing. So even if you depend on a class instead of an interface, you might end up with a subclass. Spring framework actually does this automatically in many cases.
If you find yourself needing to create objects and you're not sure that you should depend on them, have your dependency injection framework give you a Factory for those objects. How this works is obviously framework-dependent, but all frameworks that I know of support factories. If you're not using a framework, you can still write factories and use them instead of using new all the time.
If you write a code without using spring IOC container, you have to write some factory classes to create objects and hook them up. For an example instance consider a service class which has a reference to the DAO instance. You have to write some initialization factory for the service class which guarantees a singleton access to the service class and makes sure that the service class is instantiated with an instance of DAO. Creating new instances everywhere in your code is not a good practice, hence factory pattern is used. But if you use Spring IOC container it will take care of all these things. Usually it creates singleton instances so you don't need to use new keyword in your code lending you to write more clear code. Your code is loosely coupled and more maintainable with this approach. If you have only one public constructor you can now have the liberty of doing a constructor injection, without using #Autowire invasive annotation with the new spring version.
There are three DI mechanisma used in spring as stated here. Out of the three constructor injection is recommended since it is more testable and does not lead to any invariant. Field injection using #Autowire is evil and not recommended since it is not testable solution.
Hope this helps. Happy coding.
I can't believe this is so hard to figure out. I'm a Grails / Groovy newb though and what I expect is that this supposed to be done in Groovy somehow. I'm resurrecting an old project and updating it for Java 8. So far I've the libraries and dependencies fixed but one of the things I had to change was getting a reference in a Java class to org.springframework.core.env.Environment. I thought that grabbing that out of the application context would be easy but it's done in some way I don't understand.
I've been pouring over this http://docs.grails.org/2.4.5/guide/spring.html but it's still not clear. Note that where I have to wire it into is a Java class.
If this class isn't going to be a Spring bean or in some other way a candidate for dependency injection, then it's very likely called directly or indirectly from a Spring bean, e.g. as a helper for a controller, or service, or Quartz job, etc. Have the caller pass dependencies (other beans, the ApplicationContext, etc.) to it in the constructor or as method args, depending on what's more convenient.
If you can't get anything reasonable to work using dependency injection and/or passing along injected dependencies, you can always violate DI and IoC and use the grails.util.Holders antipattern class and pull in the context or Spring beans, but this should only be done if there's no proper solution.
I think my understanding of spring beans is a bit off.
I was working on my project and I was thinking about this situation.
Say I have class Foo
class Foo(){
public void doSomething(Object a , Object b){ // input parameters does not matter actually.
//do something
}
}
If I am using this class in another class like :
class Scheduler{
....
#Autowired
private Foo foo;
someMethod(){
foo.doSomeThind(a,b);
}
....
}
In the above case Instead of Autowiring the Foo, I can make doSomeThing static and directly use Foo.doSomeThing(a,b)
I was just wondering if there any advantage of creating a bean or if there any disadvantage of using static methods like this?
If they are same, When should I go for spring bean and when should do I simply use a static method?
Static methods are ok for small utility functions. The limitation of static code is that you can't change it's behavior without changing code itself.
Spring, on the other hand, gives you flexibility.
IoC. Your classes don't know about the exact implementation of their dependencies, they just rely on the API defined by interface. All connections are specified in configuration, that can be different for production/test/other.
Power of metaprogramming. You can change the behavior of your methods by merely marking them (via annotations of in xml). Thus, you can wrap method in transactions, make it asynchronous or scheduled, add custom AOP interceptors, etc.
Spring can instrument your POJO method to make it an endpoint to remote web service/RPC.
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/
Methods in Spring beans can benefit from dependency injection whereas static methods cannot. So, an ideal candidate for static method is the one that does things more or less independently and is not envisioned to ever need any other dependency (say a DAO or Service)
People use Spring not because of some narrow specific futures that cannot be replaced by static classes or DI or whatever. People use Spring because of a more abstracted features and ideas it provide out of the box.
Here is a nice quote from Someone`s blog:
Following are some of the major benefits offered by the Spring Framework:
Spring Enables POJO Programming. Spring enables programmers to develop enterprise-class applications using POJOs. With Spring, you are able to choose your own services and persistence framework. You program in POJOs and add enterprise services to them with configuration files. You build your program out of POJOs and configure it, and the rest is hidden from you.
Spring Provides Better Leverage. With Spring, more work can be done with each line of code. You code in a more fast way, and maintain less. There’s no transaction processing. Spring allows you to build configuration code to handle that. You don’t have to close the session to manage resources. You don’t have to do configuration on your own. Besides you are free to manage the exceptions at the most appropriate place not facing the necessity of managing them at this level as the exceptions are unchecked.
Dependency Injection Helps Testability. Spring greatly improves your testability through a design pattern called Dependency Injection (DI). DI lets you code a production dependency and a test dependency. Testing of a Spring based application is easy because all the related environment and dependent code is moved into the framework.
Inversion of Control Simplifies JDBC. JDBC applications are quite verbose and time-taking. What may help is a good abstraction layer. With Spring you can customize a default JDBC method with a query and an anonymous inner class to lessen much of the hard work.
Spring’s coherence. Spring is a combination of ideas into a coherent whole, along with an overall architectural vision to facilitate effective use, so it is much better to use Spring than create your own equivalent solution.
Basis on existing technologies. The spring framework is based on existing technologies like logging framework, ORM framework, Java EE, JDK timers, Quartz and other view related technologies.
During unit testing you have more flexibility using bean because you can easily mock your bean methods. However, that is not the same with static methods where you may have to resort to PowerMock (which I recommend you stay away from if you can).
It actually depends on the role of the component you are referring to: Is this feature:
An internal tooling: you can use static (you wouldn't wrap Math.abs or String.trim in a bean)
Or a module of the project: design it to be a bean/module-class (a DAO class is best modular to be able to change/mock it easily)
Globally, you should decide w.r.t your project design what are beans and what are not. I think many dev put too much stuff inside bean by default and forget that every bean is an public api that will be more difficult to maintain when refactoring (i.e. restrained visibility is a good thing).
In general, there are already several answers describing the advantages of using spring beans, so I won't develop on that. And also note that you don't need spring to use bean/module design. Then here are the main reasons not to use it:
type-safety: Spring bean are connected "only" at runtime. Not using it, you (can) get much more guaranties at compile time
It can be easier to track your code as there is no indirection due to IoC
You don't need the additional spring dependency/ies which get quite heavy
Obviously, the (3) is correct only if you don't use spring at all in your project/lib.
Also, The (1) and (2) really depend on how you code. And the most important is to have and maintain a clean, readable code. Spring provides a framework that forces you to follow some standard that many people like. I personally don't because of (1) and (2), but I have seen that in heterogeneous dev teams it is better to use it than nothing. So, if not using spring, you have to follow some strong coding guidelines.
I've read the reasons why to use (not to use) DI (see reasons below), and have a few questions.
Dependency injection is effective in these situations:
You need to inject configuration data into one or more components.
You need to inject the same dependency into multiple components.
You need to inject different implementations of the same dependency.
You need to inject the same implementation in different configurations.
You need some of the services provided by the container.
Dependency injection is not effective if:
You will never need a different implementation.
You will never need a different configuration.
Questions:
I afraid that don't understand all of them, so I hope you'll correct me if I'm wrong.
Don't understand. Is that about .properties files or I can apply the same xml configuration to multiple beans?
It's clear for me.
It's clear for me.
Don't understand. Example please.
It's clear for me.
P.S. And how often there are situations when you never need different implementations/configurations as pointed above?
Dependency injection is not effective if:
You will never need a different implementation.
You will never need a different configuration.
This isn't true: dependency injection is useful even when you are wiring statically configured objects.
In fact, your whole argumentation moves along wrong lines. The main reasons in favor of dependency injection are the separated and centralized concerns of object:
naming (each object in the DI container is given a unique name),
lookup (each object can be easily looked up by that name from anywhere else),
and wiring (providing one object with a reference to another).
In addition, a key advantage is the declarative management of object lifecycle and scoping.
Further out, Spring IoC container adds many more advantages, such as:
annotation-based wiring;
automated exception handling and reporting;
annotation-based declarative transactions;
annotation-based mapping of HTTP requests to controller methods;
... and much more.
In a nutshell, doing an application based on a DI container means you can focus on your actual business logic and have most other concerns (which repeat in each application) delegated to the container.