Autowiring Example in Spring Using XML Configuration

Annotations and Java configurations are more common in newer Spring projects. However, there are many old projects that continue to use XML configuration. Through the autowiring feature, spring will intelligently guess some of the bean injection without needing to configure explicitly. Spring can do autowiring based on the type of the bean, name of the bean, and constructor of the bean. Default is autowire by type.

We will use the same Line, Point and TestMain classes that we used for the previous note on ‘Injecting objects through spring xml’.

 

Autowiring by Name

When we autowire by name, spring looks for other beans with same id name as that of the properties that need to be autowired. We also need to tell spring to autowire by name by adding one more attribute to the bean definition:

<bean id="line" class="com.javajee.spring.Line" autowire="byName">

</bean>

Note that we don’t specify the property references within the bean element as in the previous example.

Class Line has two properties and corresponding setters and getters following javabean convention:

private Point pointA;

private Point pointB;

public Point getPointA() {

            return pointA;

}

public void setPointA(Point pointA) {

            this.pointA = pointA;

}

public Point getPointB() {

            return pointB;

}

public void setPointB(Point pointB) {

            this.pointB = pointB;

}

So our bean names should be pointA and pointB:

<bean id="pointA1" class="com.javajee.spring.Point">

<property name="x" value="1"></property>

<property name="y" value="1"></property>

</bean>

 

<bean id="pointB1" class="com.javajee.spring.Point">

<property name="x" value="10"></property>

<property name="y" value="10"></property>

</bean>

Important thing to remember here is that it is not the actual variable names that matter, but the name of the setter. If names of the setter don’t follow the javabean convention, then we need to use beans names in accordance with the setter.  For instance, if setter names alone (without property names) are changed to setPointA1 and setPointB1, then bean names should be pointA1 and pointB1.

 

Complete Spring.xml file

<?xml version="1.0" encoding="UTF-8"?>

 

<beans xmlns="http://www.springframework.org/schema/beans"

            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

 

            <bean id="line" class="com.javajee.spring.Line" autowire="byName">

            </bean>

           

            <bean id="pointA" class="com.javajee.spring.Point">

                        <property name="x" value="1"></property>

                        <property name="y" value="1"></property>

            </bean>

 

            <bean id="pointB" class="com.javajee.spring.Point">

                        <property name="x" value="10"></property>

                        <property name="y" value="10"></property>

            </bean>

</beans>

 

Autowiring by Type and Constructor

Autowiring by Type is done by changing autowire="byName" with autowire="byType". When using type to autowire, there should be only one property of that type for the bean. In our example we have two properties of the type Point and hence it will give the exception as:

UnsatisfiedDependencyException

Caused by: NoUniqueBeanDefinitionException: No qualifying bean of type [com.javajee.spring.Point] is defined: expected single matching bean but found 2

Autowiring by constructor is done by changing autowire="byName" with autowire="constructor". Autowiring by constructor is similar to type in that there should not be more than one argument with same type. Also, instead of Setter Injection in autowire by type, autowire by constructor does Constructor Injection. In this example, there are no constructor arguments, and hence you will get NullPointerException. The default autowiring is autowire off.

Basically if we think from Spring’s point of view, there should not be any confusion in determining the bean that needs to be injected.

 

Final Spring.xml file for @Autowired

<?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-4.0.xsd

    http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context-4.0.xsd">

 

            <bean id="line" class="com.javajee.spring.Line">

            </bean>

            <bean id="pointB" class="com.javajee.spring.Point">

                        <property name="x" value="10"></property>

                        <property name="y" value="10"></property>

            </bean>

            <bean id="pointA" class="com.javajee.spring.Point">

                        <property name="x" value="1"></property>

                        <property name="y" value="1"></property>

            </bean>

            <context:annotation-config />

</beans>

 

Java Class Files for Exercise

Please see previous notes for complete exercises code.

Comments

In this example, Classroom.java and Teacher.java classes are created. Testing is done by ExecutionClass.java and Application context is configured in spring.xml

Classroom class have two properties: standard - Int type, teacher - Teacher type (injecting the bean)

Teacher class have two properties: name and subject

Classroom.java

public class Classroom {

    private Teacher teacher;
    private int standard;
    
    public Classroom(Teacher teacher){
        this.teacher = teacher;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    
    public int getStandard() {
        return standard;
    }

    public void setStandard(int standard) {
        this.standard = standard;
    }
    
    public void classInfo(){
        System.out.println(getStandard()+" class Teacher is : "+getTeacher().getName()+" and handle the "+getTeacher().getSubject()+" subject.");
    }
}

Teacher.java

public class Teacher {

    private String name;
    private String subject;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }
}

spring.xml

<bean id="classroom" class="com.spring.autowiring.Classroom" autowire="constructor">
        <property name="standard" value="12"></property>
    </bean>    
    
    <bean id="teacher" class="com.spring.autowiring.Teacher">
        <property name="name" value="Heartin"></property>
        <property name="subject" value="Spring"></property>
    </bean>

ExecutionClass.java

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Classroom classroom = (Classroom) context.getBean("classroom");
        classroom.classInfo();

Output: 12 class Teacher is : Heartin and handle the Spring subject.

Was it useful?

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!