#Autowired or private final - spring

My question is simple. Which approach is more efficient?
method 1:
#Autowired
private CustomerRepository customerRepo;
method 2:
private final CustomerRepository custormerRepo;
public StudentService(CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
As I see the DI in the method2 is more recent. But I wanted to ask you which one should I use?

TL;DR: Method 2 is much more flexible.
Method 1 is an example of field injection and method 2 is an example of constructor injection.
Field injection has some drawbacks that constructor injection avoids. Here are some advantages of constructor injection:
Immutability:
You can't do this is plain Java:
#Autowired
private final CustomerRepository customerRepo;
// No constructor that sets "customerRepo".
So, Spring offers constructor injection:
private final CustomerRepository customerRepo;
#Autowired
public StudentService(final CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
Immutability is sometimes preferred. One reason is that it helps with thread-safety. Another is security.
Personally, I follow the rule, "if it can be final, it should be final."
Testing:
You won't need reflection to set the dependencies. Yes, many mocking frameworks handle this for you, but with constructor injection, you have the option to call new on the constructor.
Nasty NullPointerExceptions:
An object is created by calling its constructor, right? We usually want our arguments to be non-null at the time they are passed in. With constructor injection, the Spring IoC container makes sure that all the arguments passed in the constructor are available before passing them into the constructor.

use constructor injection, Spring also recommends it

In your main code, you should use method 2 as field injection (method 1) is not recommended. (see here for reasons)
In your test code, it's okay to use method 1.

I suggest you suggest something better. By using the Lombok library's #RequiredArgConstructor you are thus avoiding the boilerplate code. and if you wonder why #Autowired not reccomended , because of when you want to write unit testing in your application and there will be problem , where if you use #Autowired.

In addition to what the other answers have said about immutability, another benefit of constructor injection is to be able to avoid NPE is the field is not initialized. Using autowired, from a test, you’d create the class and then must remember to set the field. Using constructor injection, you can’t not initialize the field. This is more prominent in Kotlin where autowired fields are declared as lateinit var and throw a runtime exception if used before initialized. But a constructor argument can be declared as not null type which prevents you from even explicitly passing null.

Related

How Field Injection in Spring Boot works internally?

#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.

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

How does Mockito #InjectMocks work?

Here's my question:
I have several web services classes to test that all inherit their methods from a generic service. Rather than write a unit test for each, I figure I can break the test suite down by functional areas (i.e. three groups of test methods, each relying on a different underlying DAO method call).
What I propose to do is:
#Mock StateDAO mockedStateDao;
#Mock CountyDAO mockedCountyDao;
#Mock VisitorDAO mockedVisitorDao;
then call:
#InjectMocks CountyServiceImpl<County> countyService = new CountyServiceImpl<County>();
#InjectMocks StateServiceImpl<State> stateService = new StateServiceImpl<State>();
#InjectMocks VisitorServiceImpl<Visitor> visitorService = new VisitorServiceImpl<Visitor>();
How can I be sure that each mockedDAO will be injected into the correct service?
Would it be easier to autowire all three (rather than use #InjectMocks)?
I'm using Spring, Hibernate, and Mockito...
Well nicholas answer is almost correct, but instead of guessing just look at the javadoc of InjectMocks, it contains more details ;)
To me it's weird to have so many Service in a single test, it doesn't feel right, as a unit test or as an integration test. In unit test it's wrong because well you have way too much collaborators, it doesn't look like object oriented (or SOLID). In integration tests, it's weird because the code you test the integration with the DB not mock it.
For a rapid reference in 1.9.5 you have :
Mark a field on which injection should be performed.
Allows shorthand mock and spy injection.
Minimizes repetitive mock and spy injection.
Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.
Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only.
Note: If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won't happen. In these cases, you will have to satisfy dependencies yourself.
Property setter injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the property name and the mock name.
Note 1: If you have properties with the same type (or same erasure), it's better to name all #Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.
Note 2: If #InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.
Field injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the field name and the mock name.
Note 1: If you have fields with the same type (or same erasure), it's better to name all #Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen.
Note 2: If #InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.
If you have multiple Services and would like to replace the DAOs with Mock-Objects in a Spring-based environment, I would recommend to use Springockito: https://bitbucket.org/kubek2k/springockito/wiki/Home
which is also mentioned here:
Injecting Mockito mocks into a Spring bean
Your Testclass then might look like this:
#RunWith (SpringJUnit4ClassRunner.class)
#ContextConfiguration (loader = SpringockitoContextLoader.class, locations = {"classpath:/org/example/package/applicationContext.xml"})
public class NameOfClassTest {
#Autowired
#ReplaceWithMock
StateDAO mockedStateDao;
#Autowired
#ReplaceWithMock
CountyDAO mockedCountyDao;
#Autowired
#ReplaceWithMock
VisitorDAO mockedVisitorDao;
In your #Test or #Before Methode you can setup your mocks the standard Mockito way:
Mockito.doReturn(null).when(mockedCountyDao).selectFromDB();
Well, the static method MockitoAnnotations.initMocks(Object) is used to bootstrap the whole process.
I don't know for sure how it works, as I haven't browsed the source code, but I would implement it something like this:
Scan the passed Object's class for member variables with the #Mock annotation.
For each one, create a mock of that class, and set it to that member.
Scan the passed Object's class for member variables with the #InjectMocks annotation.
Scan the class of each found member for members it has that can be injected with one of the mock objects created in (2) (that is, where the field is a parent class/interface, or the same class, as the mock objects declared class) and set it to that member.
Nevermind, looked online- the InjectMocks annotation treats anything with the #Mock annotation as a field and is static-scoped (class wide), so I really couldn't guarentee that the mocks would go to the correct service. this was somewhat a thought experiment for trying to unit test at feature level rather than class level. Guess I'll just autowire this stuff with Spring...

Resources