Spring Dependency Injection Annotation#
Annotation Injection Type#
What Is The Spring Autowiring?#
- Spring can automatically wire up our objects together for injecting dependency. So basically the Spring Framework will look for a class that matched a given property and it will actually match by type. The type of the class could be interface or class. Once Spring finds a match then it'll automatically inject it. Hence it's called autowired.
Autowiring Injection Types#
- There are 3 types of autowiring injection.
- Constructor Injection
- Setter Injection
- Field Injections
Constructor Injection Annotation#
- To apply Constructor Injection for injecting dependencies with annotations, we should follow these steps below:
- Define the dependency interface and class.
- Create a constructor in our class for injections
- Configure the dependency injection with
@Autowired
annotation.
Dependency#
- We will need to add the dependency
spring-context
for creating the Spring Container andspring-core
for using Spring Annotations for configuring Constructor Injection Annotation.
pom.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Enable Component Scanning In Spring Config File#
- Now, let's create the
applicationContext.xml
file in our resources folder of our project and add configuration as below to enable components scanning.
applicationContext.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Define the dependency interface and class#
- So now, let's create 2 interfaces
Coach
andExanminationService
and they will be implemented by 2 java classesEnglishCoach
andEnghlishExaminationService
correspondingly. Then the classEnglishCoach
will need to useExanminationService
as a dependency for it's method.
- So, firstly let's create
ExaminationService
interface andEnglishExaminationService
implementation class as below.
ExaminationService.java | |
---|---|
1 2 3 4 5 6 7 |
|
EnglishExaminationService.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
- Then let's create the
Coach
interface andEnglishCoach
implementation class as below.
Coach.java | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
- As you can see, for implement classes
EnglishExaminationService
andEnglishCoach
. We use the annotation@Component
to let Spring Framework knows these are beans need to be registered during the scanning.
Create a constructor in our class for injections#
- Now, in the
EnglishCoach
, let's create a constructor and inject theExaminationService
as below.
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
- As you can see, in the constructor of
EnglishCoach
class we will inject theExaminationService
and use it forgetExamination()
method.
Configure dependency injection with @Autowired
Annotation#
- Now, Let's put the annotation
@Autowired
above the constructor that we created in theEnglishCoach
as below.
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
- So with this annotation, we will tell to the Spring Framework that let's find the component that implements the
ExaminationService
and inject it (autowired) it there.
Testing#
- Then, let's create the main class
SpringApplication
and then we will create the container with xml configuration file and get beans for using.
SpringApplication.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
- So when we run our application, we expect that we will get the information from the
EnglishExaminationService
because we injected it into theEnglishCoach
by using constructor type in xml configuration. - The successful result when run the application is show as below.
1 2 3 4 |
|
Setter Injection Annotation#
- As we known before, setter injection is injecting dependencies by calling setter method(s) on our class.
- To use the
Setter Injection
by using annotations in our Spring Framework project. We should follow steps as below:- Create setter methods in our class for injections
- Configure the dependency injection with @Autowired Annotation.
- Note: Spring Framework also provide us the ability to inject dependencies by calling ANY method on our classes.
- So, instead of using setter methods, we can actually use any method and put the @Autowired Annotation on it.
Create Setter Methods In Our Class For Injections#
- Now, we will extend the example that we made before in
Constructor Injection Annotation
with new interface and implementation class. Let's see the diagram below.
- So let's create class
HistoryExaminationService
which will implementExaminationService
interface as below
HistoryExaminationService.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- Now, let's create class
HistoryCoach
which will implementCoach
interface as below.
HistoryCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
- As you can see, in the
HistoryCoach
we will create a setter method forExaminationService
.
Configure dependency injection with @Autowired
Annotation#
- Now, Let's put the annotation
@Autowired
above the setter method that we created in theHistoryCoach
as below.
HistoryCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
- As you can see, we will put the annotation
@Autowired
above the setter method.
Qualifiers For Dependency Injection#
- Now, if we look at the diagram again, we can see the one issue that we need to handle here.
- As you can see, we have 2 implementation classes (
EnglishExaminationService
andHistoryExaminationService
) on the same interfaceExaminationService
. In which, theEnglishExaminationService
will be injected and used inEnglishCoach
and theHistoryExaminationService
will be injected and used inHistoryCoach
. -
So now, the question is how does the Spring know which implementation class that should be injected for
EnglishCoach
andHistoryCoach
?- The answer is the Spring Framework doesn't know which class it should use there, and if we run the application, an error will be thrown.
- However, Spring Framework provides for us an annotation in which we will tell to the Spring Framework which implementation bean it should use for. The annotation is
@Qualifier
.
-
When we use the bean
@Qualifier
, we have to input the value which is the bean id of the component that we want to use. Ex:@Qualifier("historyExaminationService")
.
-
We can apply
@Qualifier
annotation to:- Constructor Injection.
- Setter Injection.
- Field Injection.
-
So, let's update the
EnglishCoach
andHistoryCoach
with the annotation@Qualifier
in constructor and setter method respectively as below.
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
HistoryCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Testing#
- Then, let's update the main class
SpringApplication
for getting and using the beanhistoryCoach
as below
SpringApplication.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
- Finally, let's start our application and you should see the successful result as in the console log below. So it means, setter injection annotation and qualifier configuration have worked correctly.
1 2 3 4 5 6 |
|
Field Injection Annotation#
- With the field injection using annotation, we can inject the dependencies by setting the field values on our class directly even for private fields. This happens because behind the scene, Spring Framework use some java technology called
Reflection
. - So, to use
field injection
by using annotation, we should only to follow one step below:- Configure the dependency injection with
@Autowired
annotation. In which, we will apply directly annotation to the field and we don't need to create setter methods.
- Configure the dependency injection with
Prepare#
- We will extend the example that we made before in
Setter Injection Annotation
with new 2 implementation classes. Let's see the diagram below.
- Before going to the example, we will create more 2 classes
ScienceCoach
andScienceExaminationService
which will implementCoach
andExaminationService
respectively as below.
ScienceExaminationService.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
ScienceCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
- As you can see, in the
ScienceCoach
, we will declareexaminationService
as an attribute without setter/getter method.
Configure dependency injection with @Autowired
Annotation#
- Now, in the
ScienceCoach
, we just need to set 2 annotations@Autowired
and@Qualifier("scienceExaminationService")
on the attributeexaminationService
directly as below and that's all for the field injection annotation configuration.
ScienceCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Testing#
- Then, let's update the main class
SpringApplication
for getting and using the beanscienceCoach
as below.
SpringApplication.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
- Finally, let's start our application and you should see the successful result as in the console log below. So it means, field injection annotation and qualifier configuration have worked correctly.
1 2 3 4 5 6 7 8 |
|
Inject Values From Properties File By Annotation#
- From the section above, we learnt how to use
Field Injection Type With Annotation
for DI. In this section, we will continue to use it for injecting values from theproperties
files in ourresources
folders.
- To use the
Field Injection
for injecting values from theproperties
file in our Spring, we should follow these steps:- Create Properties File.
- Load Properties File in Spring config file
- Reference values from Properties file With Annotation
Prepare#
- So, Let's continue with the example that we did from the last section
Field Injection Annotation
. In theHistoryCoach
andEnglishCoach
classes, we will set new attributesteamEmail
withgetter
methods for them as below.
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
HistoryCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
Create Properties File#
- Let's create a properties file with name
application.properties
in our projectresources
as below.
application.properties | |
---|---|
1 2 |
|
- As you can see in the
application.properties
we have 2 variable withname
andvalue
.name
is the left part of=
value
is the right part of=
Load Properties File In Spring Config File#
- To load variables from
application.properties
, we just need to add the tagcontext:property-placeholder
withlocation
attribute as below intoapplicationContext.xml
.
applicationContext.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- In which, the value of attribute
location
incontext:property-placeholder
tag should be start withclasspath:
then the properties's file name will be put after.
Reference Values From Properties File With Annotation#
- Now, to reference values from the
application.properties
file intoHistoryCoach
andEnglishCoach
beans, we will use@Value
annotation withvalue
is the name of variable that we defined in theapplication.properties
file (coach.team.english.email
andcoach.team.history.email
) and these names have to be put in the syntax${<variable name>}
. Ex:@Value("${coach.team.english.email}")
. With this syntax Spring will load the value of that variable for us directly. - Now, let's put the
@Value
annotation on theteamEmail
fields forEnglishCoach
andHistoryCoach
classes as below.
EnglishCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
HistoryCoach.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Testing#
- Finally, let's update our
SpringApplication
for getting and using beanEnglishCoach
andhistoryCoach
with injected values from theapplication.properties
file as below.
SpringApplication.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
- Then when our application run, we will see the successful result as below. We can see the values in the
application.properties
which are injected and used byEnglishCoach
andHistoryCoach
.
1 2 3 4 5 6 7 8 9 10 |
|
Annotations - Default Bean Name - The Special Case#
- In general, when using Annotations, for the default bean name, Spring uses the following rule.
-
If the annotation's value doesn't indicate a bean name, an appropriate name will be built based on the short name of the class (with the first letter lower-cased).
- For example: ScienceExaminationService --> scienceExaminationService
-
However, for the special case of when BOTH the first and second characters of the class name are upper case, then the name is NOT converted.
- For example: RESTScienceExaminationService --> RESTScienceExaminationService (No conversion since the first two characters are upper case.)
- Behind the scenes, Spring uses the Java Beans Introspector to generate the default bean name.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
See Also#
- Spring Overview
- Spring Inversion Of Control
- Spring Dependency Injection
- Spring Dependency Injection XML