How Field Injection in Spring Boot works internally? - spring-boot

#Autowired
UserService userService;
What happens exactly inside `#Autowired annotation whether it uses Constructor Injection or Setter Injection. I know that it is field Injection.
I'm not asking How IOC or DI works, I'm asking How Field Injection in Spring Boot works internally?

Basically field inject is a type of injection (obviously), so Spring injects dependency based on field type and maybe some annotations (like #Qualifier).
How does it work?
When Spring creates a bean, there is a special Bean Post Processor org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
Each field marked with #Autowired is considered by spring as a dependency, so it must analyze these dependencies (by using reflection under the hood) and find a match from the application context for each field (by Type, qualifier if specified, etc.). Then it sets the value, right into the field, again by reflection.
I don't intend to start "holly-wars" here, but I'll just mention that I personally try to avoid using this type of injection because it effectively breaks encapsulation of dependencies, making the class with autowired fields non-unit testable.
For example if you have something like this:
#Component
class Foo {
#Autowired
private Bar bar;
public Foo() {} // no-arg construction that exists by default
}
#Component
class Bar {
}
Then when you create an instance of Foo by yourself (e.g. in unit-test) you have no clear way to supply the Bar dependency to Foo instance without relying on spring.
Constructor Injection solves this for example.

Related

Spring Boot application.properties appear unregistered when accessed from constructor

This is the code that I have:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
public Program() {
System.out.println(appTitle);
}
}
The application.properties has
app.title=The Program
The output is null insteaf of The Program.
So, what am I missing? I have tried several examples; none worked.
Since appTitle is an autowired field, it is not set until after the object is initially constructed. This is why the value is still null in your example. The bean construction process in this scenario is as follows:
The Program constructor is called, creating a new Program instance
The appTitle field is set on the newly constructed bean to ${app.title}
The ideal fix for this depends on your goals. If you truly need the value within the constructor, you can pass it in as an autowired constructor parameter. The value will then be available within the constructor:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
public Program(#Value("${app.title}") appTitle) {
System.out.println(appTitle);
}
}
If you don't need it in the constructor itself, but need it for the proper initialization of the bean, you could alternatively use the #javax.annotation.PostConstruct annotation to make use of it after the object's construction but before it is made available for use elsewhere:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
#PostConstruct
public void printAppTitle() {
System.out.println(appTitle);
}
}
Finally, if you don't need the value at construction time, but need it during the life of the bean, what you have will work; it just won't be available within the body of the constructor itself:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
}
Nothing wrong, just don't do it in a constructor...
Other answers on this question are written assuming the goal is creating a Spring-managed bean that uses the given property in its creation. However, based on your comments in another answer, it looks like the question you want answered is how to access an externalized property (one provided by #Value) within a no-argument constructor. This is based on your expectation that a Java inversion of control (IoC) container such as Spring should allow accessing externalized properties (and presumably other dependencies) within a no-argument constructor. That being the case, this answer will address the specific question of accessing the property within a no-argument constructor.
While there are certainly ways this goal could be achieved, none of them would be idiomatic usage of the Spring framework. As you discovered, autowired fields (i.e. fields initialized using setter injection) cannot be accessed within the constructor.
There are two parts to explaining why this is. First, why does it work the way it does, programmatically? Second, why was it designed the way it was?
The setter-based dependency injection section of the Spring docs addresses the first question:
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.
In this case, it means that first the object is created using the no-argument constructor. Second, once the object is constructed, the appTitle is initialized on the constructed bean. Since the field isn't initialized until after the object is constructed, it will have its default value of null within the constructor.
The second question is why Spring is designed this way, rather than somehow having access to the property within the constructor. The constructor-based or setter-based DI? sidebar within the Spring documentation makes it clear that constructor arguments are in fact the idiomatic approach when dealing with mandatory dependencies in general.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. [...]
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. [...]
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. [...]
A property needed to construct the object certainly would be categorized as a mandatory dependency. Therefore, idiomatic Spring usage would be to pass in this required value in the constructor.
So in summary, trying to access an application property within a no-argument constructor is not supported by the Spring framework, and in fact runs contrary to the recommended use of the framework.

Methods of Autowiring in Spring - Difference between the two possible alternatives below

I have a basic Auto-wiring Question. I see the following two implementations that are possible in Spring auto-wiring
Method1
public class SimpleMovieLister {
private MovieFinder movieFinder;
#Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
Method2
public class SimpleMovieLister {
#Autowired
private MovieFinder movieFinder;
}
My understanding is that both are the same and I use a lot of Method2 in my code. What are the situations in which Method1 is useful ? Or is it just a case of Spring evolution and we have both possible ways in which to implement.
Sorry, if the question is too basic, but I need to get this cleared up
Method 1 is Setter Injection.
Method 2 is Field Injection.
A 3rd method is Constructor Injection
Example:
public class SimpleMovieLister {
private MovieFinder movieFinder;
#Autowired
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
Method 3, Constructor Injection is preferred because it makes testing significantly easier since you can pass in the required dependency.
Also, if your Bean only has 1 Constructor, then you can omit the #Autowired annotation. Spring will automatically choose that constructor method when creating the bean.
A good snippet from the docs:
The Spring team generally advocates constructor injection as it
enables one to implement application components as immutable objects
and to ensure that required dependencies are not null. Furthermore
constructor-injected components are always returned to client
(calling) code in a fully initialized state. As a side note, a large
number of constructor arguments is a bad code smell, implying that the
class likely has too many responsibilities and should be refactored to
better address proper separation of concerns.
Setter injection should primarily only be used for optional
dependencies that can be assigned reasonable default values within the
class. Otherwise, not-null checks must be performed everywhere the
code uses the dependency. One benefit of setter injection is that
setter methods make objects of that class amenable to reconfiguration
or re-injection later. Management through JMX MBeans is therefore a
compelling use case for setter injection.
Use the DI style that makes the most sense for a particular class.
Sometimes, when dealing with third-party classes for which you do not
have the source, the choice is made for you. For example, if a
third-party class does not expose any setter methods, then constructor
injection may be the only available form of DI.
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html
Method 1 is setter Injection
Setter injection should primarily only be used for optional
dependencies that can be assigned reasonable default values within the
class. Otherwise, not-null checks must be performed everywhere the
code uses the dependency. One benefit of setter injection is that
setter methods make objects of that class amenable to reconfiguration
or re-injection later.
Method 2 is field Injection

Is #Autowired annotation used correctly?

I use #Autowired annotation like this:
#Autowired
private MyService1 myService1;
#Autowired
private MyService2 myService2;
But new Intellij IDE 2016(3) suggests and proposes to replace:
private final MyService1 myService1;
private final MyService2 myService2;;
#Autowired
public MyClass(MyService1 myService1, MyService2 myService2) {
this.myService1= myService1;
this.myService2= myService2;
}
Tell me what is the difference and what is right?
Both approaches are correct.
From docs
Spring included, provide a mechanism for ensuring that all dependencies are defined when you use Setter Injection, but by using Constructor Injection, you assert the requirement for the dependency in a container-agnostic manner"
#Autowire at constructor level guarantees that you will have all the required dependencies when your spring container finally creates your bean for that class.
It is suggecting to using constructor inject instead of Setter inject. For nomal use, there is no big different.
We usually advise people to use constructor injection for all mandatory collaborators and setter injection for all other properties. Again, constructor injection ensures all mandatory properties have been satisfied, and it is simply not possible to instantiate an object in an invalid state (not having passed its collaborators). In other words, when using constructor injection you do not have to use a dedicated mechanism to ensure required properties are set (other than normal Java mechanisms).
Here is an article to explain it Setter injection versus constructor injection and the use of #Required
Also you can get quite a lot question/answer in stackoverflow.
Setter DI vs. Constructor DI in Spring?
Yes, it is used correctly. This is called the Constructor Injection.
Constructor Injection allows you to use the final modifiers of your choice and to easily pass your own not managed by Spring objects (mocks, for example).
If you are not forced to using field injection, choose constructor injection.

Ways in which Spring do Dependency Injection

I have some experience in Spring Framework. Spring usually do the DI using the constructor injection or setter injection. This concept I am comfortable. Now, in addition to this, I have seen the Spring do DI like this:
#Autowired
DataSource myData;
OR
#Resouce(name="someName")
SomeDependency dependency;
What mechanism do Spring utilise when it uses annotations to do the DI? Does Spring use constructor or setter injection in these cases or is annotation driven approach altogether a different way of injecting the dependencies?
Any explanation in simple worlds would be of great help.
You can do setter injection and constructor injection by #Autowired means.
#Autowired
private Person person;
#Autowired
public Customer(Person person) {
this.person = person;
}
By default autowired inject beans by TYPE. Behind the scene it makes injection via java reflection mechanism. So you can do the same things(that you've done with xml config) with annotation config.
In addition want to add that constructor injection is more preferable(except cases where there are to much arguments).
Main advantage of constructor injection:
You can't avoid passing arguments to constructor and create bean without them.
So in most all cases you want dependency to be injected, while setter injection doesn't guarantee it(you can get this annoying NPE that appears during wrong setter injection).
Specific rules of autowired using :
http://docs.spring.io/spring/docs/4.2.7.RELEASE/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html

Spring DI? Interface Type?

I understand the how, but can't seem formally shape the definitions.
As known DI can be done via constructor or setter or interface.
I am confused about the latest one -interface based DI, is it used in Spring?
UPDATE: I gave bad examle in here, which led to wrong understanding.
To fix it up:
Say we have setter and in setter we inject interface implemented by some class. Is that considered DI via setter or interface?
http://martinfowler.com/articles/injection.html#UsingAServiceLocator
this article divides DI on:
"There are three main styles of dependency injection. The names I'm using for them are Constructor Injection, Setter Injection, and Interface Injection. If you read about this stuff in the current discussions about Inversion of Control you'll hear these referred to as type 1 IoC (interface injection), type 2 IoC (setter injection) and type 3 IoC (constructor injection). I find numeric names rather hard to remember, which is why I've used the names I have here."
Else Service Locator pattern used for IoC, is it the one that actually makes possible #Autowired? - ie that not all classes explicitly need to be declared in xml for DI, as we can declare them as #Repository or #Controller or alike again if I recall correctly.
Thanks,
Autowiring an interface means wire a bean implementing that interface. This relies on an implementation actually existing in the bean factory.
#Autowired
UserService us; // wire a bean implementing UserService
--
#Service
public class UserServiceImpl implements UserService {
// the #Service annotation causes this implementation of UserService to
// be made available for wiring in the bean factory.
}
Worth noting is that if you wire by interface, Spring will expect there to exist one and exactly one bean in the bean factory implementing that interface. If more than one bean is found, an error will be thrown and you will have to specify which bean to wire (using the #Qualifier annotation).
EDIT:
When wiring, you can either wire a member variable or a setter method.
#Autowired
UserService us;
--
#Autowired
public void setUserService(UserService us) {
this.us = us;
}
These two produce the same result. The difference is that in the former, Spring will use reflection to set the variable us to a bean implementing UserService. In the latter, Spring will invoke the setUserService method, passing the same UserService imlementation.

Resources