Skip to content

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 and spring-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
....  

<dependencies>  

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-context</artifactId>  
        <version>5.3.24</version>  
    </dependency>  

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-core</artifactId>  
        <version>5.3.24</version>  
    </dependency>

</dependencies>

....

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.core.spring.dependency.injection.annotation"/>

</beans>

Define the dependency interface and class#

  • So now, let's create 2 interfaces Coach and ExanminationService and they will be implemented by 2 java classes EnglishCoach and EnghlishExaminationService correspondingly. Then the class EnglishCoach will need to use ExanminationService as a dependency for it's method.

 #zoom

  • So, firstly let's create ExaminationService interface and EnglishExaminationService implementation class as below.
ExaminationService.java
1
2
3
4
5
6
7
package com.spring.core.spring.dependency.injection.annotation;

public interface ExaminationService {

    public String getExamination();

}
EnglishExaminationService.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.stereotype.Component;

@Component
public class EnglishExaminationService implements ExaminationService {

    @Override
    public String getExamination() {
        return "Focus and take English examination in 3 hours";
    }
}
  • Then let's create the Coach interface and EnglishCoach implementation class as below.
Coach.java
1
2
3
4
5
6
7
8
9
package com.spring.core.spring.dependency.injection.annotation;

public interface Coach {

    public String getDailyHomeWork();

    public String getExamination();

}
EnglishCoach.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return null;
    }

}
  • As you can see, for implement classes EnglishExaminationService and EnglishCoach. 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 the ExaminationService 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    private final ExaminationService examinationService;

    public EnglishCoach(ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

}
  • As you can see, in the constructor of EnglishCoach class we will inject the ExaminationService and use it for getExamination() method.

Configure dependency injection with @Autowired Annotation#

  • Now, Let's put the annotation @Autowired above the constructor that we created in the EnglishCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    private final ExaminationService examinationService;

    @Autowired
    public EnglishCoach(ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

}
  • 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApplication {

    public static void main(String[] args) {

        //create Spring Container with configuration file
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Get bean from container
        Coach englishCoach = context.getBean("englishCoach", Coach.class);

        //use bean
        System.out.println(englishCoach.getDailyHomeWork());
        System.out.println(englishCoach.getExamination());

        //close container
        context.close();
    }

}
  • So when we run our application, we expect that we will get the information from the EnglishExaminationService because we injected it into the EnglishCoach by using constructor type in xml configuration.
  • The successful result when run the application is show as below.
1
2
3
4
Spend 1 hour to practise Speaking Skill!
Focus and take English examination in 3 hours

Process finished with exit code 0

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.

 #zoom

  • So let's create class HistoryExaminationService which will implement ExaminationService interface as below
HistoryExaminationService.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.stereotype.Component;

@Component
public class HistoryExaminationService implements ExaminationService {

    @Override
    public String getExamination() {
        return "Focus and take History examination in 3 hours";
    }

}
  • Now, let's create class HistoryCoach which will implement Coach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.stereotype.Component;

@Component
public class HistoryCoach implements Coach {

    private ExaminationService examinationService;

    @Override
    public String getDailyHomeWork() {
        return "Spend 20 minutes to read history books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    public void setExaminationService(ExaminationService examinationService) {
        this.examinationService = examinationService;
    }
}
  • As you can see, in the HistoryCoach we will create a setter method for ExaminationService.

Configure dependency injection with @Autowired Annotation#

  • Now, Let's put the annotation @Autowired above the setter method that we created in the HistoryCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HistoryCoach implements Coach {

    private ExaminationService examinationService;

    @Override
    public String getDailyHomeWork() {
        return "Spend 20 minutes to read history books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    @Autowired
    public void setExaminationService(ExaminationService examinationService) {
        this.examinationService = examinationService;
    }
}
  • 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.

 #zoom

  • As you can see, we have 2 implementation classes (EnglishExaminationService and HistoryExaminationService) on the same interface ExaminationService. In which, the EnglishExaminationService will be injected and used in EnglishCoach and the HistoryExaminationService will be injected and used in HistoryCoach.
  • So now, the question is how does the Spring know which implementation class that should be injected for EnglishCoach and HistoryCoach?

    • 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").

 #zoom

  • We can apply @Qualifier annotation to:

    • Constructor Injection.
    • Setter Injection.
    • Field Injection.
  • So, let's update the EnglishCoach and HistoryCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    private final ExaminationService examinationService;

    @Autowired
    public EnglishCoach(@Qualifier("englishExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

}
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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class HistoryCoach implements Coach {

    private ExaminationService examinationService;

    @Override
    public String getDailyHomeWork() {
        return "Spend 20 minutes to read history books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    @Autowired
    public void setExaminationService(@Qualifier("historyExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }
}

Testing#

  • Then, let's update the main class SpringApplication for getting and using the bean historyCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApplication {

    public static void main(String[] args) {

        //create Spring Container with configuration file
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Get bean from container
        Coach englishCoach = context.getBean("englishCoach", Coach.class);
        Coach historyCoach = context.getBean("historyCoach", Coach.class);

        //use beans
        System.out.println(englishCoach.getDailyHomeWork());
        System.out.println(englishCoach.getExamination());
        System.out.println(historyCoach.getDailyHomeWork());
        System.out.println(historyCoach.getExamination());

        //close container
        context.close();
    }

}
  • 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
Spend 1 hour to practise Speaking Skill!
Focus and take English examination in 3 hours
Spend 20 minutes to read history books
Focus and take History examination in 3 hours

Process finished with exit code 0

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.

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.

 #zoom

  • Before going to the example, we will create more 2 classes ScienceCoach and ScienceExaminationService which will implement Coach and ExaminationService respectively as below.
ScienceExaminationService.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.spring.core.spring.dependency.injection.annotation;  

import org.springframework.stereotype.Component;  

@Component  
public class ScienceExaminationService implements ExaminationService {  

    @Override  
    public String getExamination() {  
        return "Focus and take Science examination in 3 hours";  
    }  
}
ScienceCoach.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.stereotype.Component;

@Component
public class ScienceCoach implements Coach {

    private ExaminationService examinationService;

    @Override
    public String getDailyHomeWork() {
        return "Spend 40 minutes to read science books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

}
  • As you can see, in the ScienceCoach, we will declare examinationService 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 attribute examinationService 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class ScienceCoach implements Coach {

    @Autowired
    @Qualifier("scienceExaminationService")
    private ExaminationService examinationService;

    @Override
    public String getDailyHomeWork() {
        return "Spend 40 minutes to read science books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

}

Testing#

  • Then, let's update the main class SpringApplication for getting and using the bean scienceCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApplication {

    public static void main(String[] args) {

        //create Spring Container with configuration file
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Get bean from container
        Coach englishCoach = context.getBean("englishCoach", Coach.class);
        Coach historyCoach = context.getBean("historyCoach", Coach.class);
        Coach scienceCoach = context.getBean("scienceCoach", Coach.class);

        //use beans
        System.out.println(englishCoach.getDailyHomeWork());
        System.out.println(englishCoach.getExamination());
        System.out.println(historyCoach.getDailyHomeWork());
        System.out.println(historyCoach.getExamination());
        System.out.println(scienceCoach.getDailyHomeWork());
        System.out.println(scienceCoach.getExamination());

        //close container
        context.close();
    }

}
  • 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
Spend 1 hour to practise Speaking Skill!
Focus and take English examination in 3 hours
Spend 20 minutes to read history books
Focus and take History examination in 3 hours
Spend 40 minutes to read science books
Focus and take Science examination in 3 hours

Process finished with exit code 0

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 the properties files in our resources folders.

 #zoom

  • To use the Field Injection for injecting values from the properties 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 the HistoryCoach and EnglishCoach classes, we will set new attributes teamEmail with getter 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    private final ExaminationService examinationService;

    private String teamEmail;

    @Autowired
    public EnglishCoach(@Qualifier("englishExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    public String getTeamEmail() {
        return teamEmail;
    }

}
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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class HistoryCoach implements Coach {

    private ExaminationService examinationService;

    private String teamEmail;

    @Override
    public String getDailyHomeWork() {
        return "Spend 20 minutes to read history books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    @Autowired
    public void setExaminationService(@Qualifier("historyExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    public String getTeamEmail() {
        return teamEmail;
    }

}

Create Properties File#

  • Let's create a properties file with name application.properties in our project resources as below.
application.properties
1
2
coach.team.english.email=englishCoach@example.com  
coach.team.history.email=historyCoach@example.com
  • As you can see in the application.properties we have 2 variable with name and value.
    • 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 tag context:property-placeholder with location attribute as below into applicationContext.xml.
applicationContext.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.core.spring.dependency.injection.annotation"/>
    <context:property-placeholder location="classpath:application.properties"/>

</beans>
  • In which, the value of attribute location in context:property-placeholder tag should be start with classpath: 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 into HistoryCoach and EnglishCoach beans, we will use @Value annotation with value is the name of variable that we defined in the application.properties file (coach.team.english.email and coach.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 the teamEmail fields for EnglishCoach and HistoryCoach 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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class EnglishCoach implements Coach {

    private final ExaminationService examinationService;

    @Value("${coach.team.english.email}")
    private String teamEmail;

    @Autowired
    public EnglishCoach(@Qualifier("englishExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    @Override
    public String getDailyHomeWork() {
        return "Spend 1 hour to practise Speaking Skill!";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    public String getTeamEmail() {
        return teamEmail;
    }

}
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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class HistoryCoach implements Coach {

    private ExaminationService examinationService;

    @Value("${coach.team.history.email}")
    private String teamEmail;

    @Override
    public String getDailyHomeWork() {
        return "Spend 20 minutes to read history books";
    }

    @Override
    public String getExamination() {
        return this.examinationService.getExamination();
    }

    @Autowired
    public void setExaminationService(@Qualifier("historyExaminationService") ExaminationService examinationService) {
        this.examinationService = examinationService;
    }

    public String getTeamEmail() {
        return teamEmail;
    }

}

Testing#

  • Finally, let's update our SpringApplication for getting and using bean EnglishCoach and historyCoach with injected values from the application.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
package com.spring.core.spring.dependency.injection.annotation;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApplication {

    public static void main(String[] args) {

        //create Spring Container with configuration file
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Get bean from container
        Coach englishCoach = context.getBean("englishCoach", Coach.class);
        Coach historyCoach = context.getBean("historyCoach", Coach.class);
        Coach scienceCoach = context.getBean("scienceCoach", Coach.class);

        EnglishCoach englishCoachDetail = context.getBean("englishCoach", EnglishCoach.class);
        HistoryCoach historyCoachDetail = context.getBean("historyCoach", HistoryCoach.class);

        //use beans
        System.out.println(englishCoach.getDailyHomeWork());
        System.out.println(englishCoach.getExamination());
        System.out.println(historyCoach.getDailyHomeWork());
        System.out.println(historyCoach.getExamination());
        System.out.println(scienceCoach.getDailyHomeWork());
        System.out.println(scienceCoach.getExamination());

        System.out.println(englishCoachDetail.getTeamEmail());
        System.out.println(historyCoachDetail.getTeamEmail());

        //close container
        context.close();
    }

}
  • 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 by EnglishCoach and HistoryCoach.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Spend 1 hour to practise Speaking Skill!
Focus and take English examination in 3 hours
Spend 20 minutes to read history books
Focus and take History examination in 3 hours
Spend 40 minutes to read science books
Focus and take Science examination in 3 hours
englishCoach@example.com
historyCoach@example.com

Process finished with exit code 0

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

    /**
     * Utility method to take a string and convert it to normal Java variable
     * name capitalization.  This normally means converting the first
     * character from upper case to lower case, but in the (unusual) special
     * case when there is more than one character and both the first and
     * second characters are upper case, we leave it alone.
     * <p>
     * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
     * as "URL".
     *
     * @param  name The string to be decapitalized.
     * @return  The decapitalized version of the string.
     */
    public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

......

See Also#

References#