Beans

Spring Dependency Checking Example

This is an example of how to check dependencies in a Spring Bean. A Spring Bean can have dependencies of any type, such as primitive types, Collections or even Objects that are references to other beans. Sometimes it is necessary that specific dependencies have to be set, so that a Spring Bean is instantiated correctly.

Spring provides developers the ability to check if all mandatory dependencies of a Spring Bean have been set, either by using the @Required annotation or by defininig a custom @Required-style annotation by themselves. Furthermore, older Spring releases have offered developers the ability to check dependencies in different modes, via XML-configuration. This way is though deprecated now.

Let’s check a Spring Bean’s dependencies using all possible ways.

Our preferred development environment is Eclipse. We are using Eclipse Juno (4.2) version, along with Maven Integration plugin version 3.1.0. You can download Eclipse from here and Maven Plugin for Eclipse from here. The installation of Maven plugin for Eclipse is out of the scope of this tutorial and will not be discussed. We are also using Spring version 3.2.3 and the JDK 7_u_21.

Let’s begin.

1. Create a new Maven project

Go to File -> Project ->Maven -> Maven Project.

New-Maven-Project

In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.

Maven-Project-Name-Location

In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.snippets.enterprise" and the “Artifact Id” variable to "springexample". The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.springexample" and the project name as "springexample". Hit “Finish” to exit the wizard and to create your project.

Configure-Maven-Project

The Maven project structure is shown below:

Maven-project-structure

    It consists of the following folders:

  • /src/main/java folder, that contains source files for the dynamic content of the application,
  • /src/test/java folder contains all source files for unit tests,
  • /src/main/resources folder contains configurations files,
  • /target folder contains the compiled and packaged deliverables,
  • the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.

2. Add Spring 3.2.3 dependency

  • Locate the “Properties” section at the “Overview” page of the POM editor and perform the following changes:
    Create a new property with name org.springframework.version and value 3.2.3.RELEASE.
  • Navigate to the “Dependencies” page of the POM editor and create the following dependencies (you should fill the “GroupId”, “Artifact Id” and “Version” fields of the “Dependency Details” section at that page):
    Group Id : org.springframework Artifact Id : spring-web Version : ${org.springframework.version}

Alternatively, you can add the Spring dependencies in Maven’s pom.xml file, by directly editing it at the “Pom.xml” page of the POM editor, as shown below:
 
pom.xml:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javacodegeeks.snippets.enterprise</groupId>
    <artifactId>springexample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>
 
    <properties>
        <spring.version>3.2.3.RELEASE</spring.version>
    </properties>
</project>

As you can see Maven manages library dependencies declaratively. A local repository is created (by default under {user_home}/.m2 folder) and all required libraries are downloaded and placed there from public repositories. Furthermore intra – library dependencies are automatically resolved and manipulated.

3. Check dependencies using the @Required annotation

The typical way to check a bean’s dependencies is the @Required annotation. It can be applied to setter methods of the bean properties that are mandatory for the bean instantiation.

Here, the employeeBean has a property that is annotated as @Required in its setter, so the bean cannot be created if this property is not set in the bean definition. Similarly, the personBean has a property that is reference to another bean and since it is also annotated as @Required in its setter the bean cannot be created if the reference bean is not set in its definition.
 
Employee.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.javacodegeeks.snippets.enterprise.services;
 
import org.springframework.beans.factory.annotation.Required;
 
public class Employee {
     
    private Long id;
 
    private String position;
     
    public Long getId() {
        return id;
    }
 
    @Required
    public void setId(Long id) {
        this.id = id;
    }
     
    public String getPosition() {
        return position;
    }
 
    public void setPosition(String position) {
        this.position = position;
    }
     
    @Override
    public String toString(){
        return "id "+ id + " and position " + position;
    }
}

 
Person.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.javacodegeeks.snippets.enterprise.services;
 
import org.springframework.beans.factory.annotation.Required;
 
 
public class Person {
 
    private String name;
     
    private Employee employee;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Employee getEmployee() {
        return employee;
    }
 
    @Required
    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
 
    @Override
    public String toString(){
        return "Person " + name + " is an employee, with " + employee + ".";
    }
}

In order that the @Required annotation is set correctly to check on Spring dependencies the RequiredAnnotationBeanPostProcessor has to be set. This class allows developers to annotate the setter properties of their own classes with annotations to indicate that the container must check for the configuration of a dependency injected value. The RequiredAnnotationBeanPostProcessor can be enabled in two ways.

One way is to include <context:annotation-config/> element in applicationContext.xml, as shown below:
 
applicationContext.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
 
 <context:annotation-config />
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee">
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

The other way is to define the RequiredAnnotationBeanPostProcessor as a bean in applicationContext.xml, as shown below:
 
applicationContext.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
 
  <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee">
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

4. Define a custom Required-style annotation for dependency checking

A second way to check the dependencies of a Spring bean is by creating a custom annotation of the same style as @Required annotation. The annotation will be equivalent to @Required annotation. Here, the @Mandatory interface is created.
 
Mandatory.java

01
02
03
04
05
06
07
08
09
10
11
12
package com.javacodegeeks.snippets.enterprise.interfaces;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
  
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {
 
}

The @Mandatory annotation is applied in the employee property setter of Person bean to replace the @Required annotation.
 
Person.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.javacodegeeks.snippets.enterprise.services;
 
import com.javacodegeeks.snippets.enterprise.interfaces.Mandatory;
 
 
public class Person {
 
    private String name;
     
    private Employee employee;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Employee getEmployee() {
        return employee;
    }
 
    @Mandatory
    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
 
    @Override
    public String toString(){
        return "Person " + name + " is an employee, with " + employee + ".";
    }
}

The RequiredAnnotationBeanPostProcessor is necessary in this case too, so that the custom annotation is registered to Spring. In this case though, it needs a property, that is the new annotation to be registered. The property name is requiredAnnotationType and its value is set to the class path of the Mandatory interface.
 
applicationContext.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
 <bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
    <property name="requiredAnnotationType" value="com.javacodegeeks.snippets.enterprise.interfaces.Mandatory"/>
</bean>
  
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee">
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

5. Run the application

In both cases above, we can load the personBean and check what happens if its required dependency is missing. In App.class the bean is loaded and its toString() method is called to get its properties.
 
App.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.javacodegeeks.snippets.enterprise;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.javacodegeeks.snippets.enterprise.services.Person;
 
public class App {
     
    @SuppressWarnings("resource")
    public static void main(String[] args) {
     
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
                         
            Person person = (Person) context.getBean("personBean");
             
            System.out.println(person.toString());
    }
}

The result is shown below:

Want to master Spring Framework ?
Subscribe to our newsletter and download the Spring Framework Cookbook right now!
In order to help you master the leading and innovative Java framework, we have compiled a kick-ass guide with all its major features and use cases! Besides studying them online you may download the eBook in PDF format!

Person John is an employee, with id 123 and position marketing.

Now, if we remove the required employee property from personBean definition in applicationContext.xml and try to run the same application again, a BeanInitializationException will be thrown in both cases. The same exception will occur if we remove the id property from employeeBean definition.

6. Use check modes via XML – configuration (Spring 2.5 and older releases)

Another way that Spring older releases have provided to check beans’ dependencies was by using the dependency-check attribute inside the bean element in the bean definition. There were four different modes for the dependency check, as described below:
 
No dependency-check applicationContext.xml
The default mode, where no dependency check is performed.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee" >
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

 
Simple dependency-check applicationContext.xml
In this mode all primitive or collection types in the bean definition are checked.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person" dependency-check="simple">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee" >
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

 
Object dependency-check applicationContext.xml
In this mode all objects that are reference to other beans are checked.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person" dependency-check="objects">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee" >
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

 
All dependency-check applicationContext.xml
In this mode all dependencies are checked in bean definition.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
 
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person" dependency-check="all">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee" >
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

 
Global dependency-check applicationContext.xml
In this mode all dependencies of all bean definitions are checked in applicationContext.xml.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
    default-dependency-check="all">
    <bean id="personBean" class = "com.javacodegeeks.snippets.enterprise.services.Person">
        <property name="name" value="John"/>
        <property name="employee" ref="employeeBean"/>
    </bean>
     
        <bean id="employeeBean" class="com.javacodegeeks.snippets.enterprise.services.Employee" >
        <property name="id" value="123"/>
        <property name="position" value="marketing"/>
    </bean>
 
</beans>

Note that in all modes if any of the required properties is missing an UnsatisfiedDependencyException will be thrown in bean instantiation. As mentioned above, the XML-configuration checking with the dependency-check attribute is now deprecated.
 
This was an example of how to check dependencies in a Spring Bean.
 
Download the Eclipse project of this tutorial : SpringDependencyCheckingExample.zip

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Theodora Fragkouli

Theodora has graduated from Computer Engineering and Informatics Department in the University of Patras. She also holds a Master degree in Economics from the National and Technical University of Athens. During her studies she has been involved with a large number of projects ranging from programming and software engineering to telecommunications, hardware design and analysis. She works as a junior Software Engineer in the telecommunications sector where she is mainly involved with projects based on Java and Big Data technologies.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button