Injecting Object Dependencies in Spring Through XML Configuration

We saw how to inject primitive types and String properties through setter injection and constructor injection. We will see how to inject other objects. A class might have references to other classes and when an object of the outer class is created, Spring can inject objects for the referenced inner objects as well based on bean definitions. We will follow the xml style configuration here, but this can also be done without using XML.

 

Problem Statement

We will have a Point class with x and y coordinates, and then a Line class that references two Point objects. We will get an instance of the Line class using getBean() and Spring will inject the Point objects into the Line object based on bean definitions.

 

Java Classes

First, we will see the class files used here and then the Spring xml file that defines beans and their references; you can refer to previous notes on how to compile and execute them with required jars.

 

Point.java

package com.javajee.spring;

public class Point {

            private int x;

            private int y;

            public int getX() {

                        return x;

            }

            public void setX(int x) {

                        this.x = x;

            }

            public int getY() {

                        return y;

            }

            public void setY(int y) {

                        this.y = y;

            }

}

 

Line.java

package com.javajee.spring;

public class Line {

            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;

            }

            public void draw() {

                        System.out.println("Point A = " + getPointA().getX() + ", "

                                                + getPointA().getY() + ", Point B = " + getPointB().getX()

                                                + ", " + getPointB().getY());

            }

}

 

TestMain.java

package com.javajee.spring;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class TestMain {

            public static void main(String[] args) {

                        ApplicationContext context =

                                                new ClassPathXmlApplicationContext("spring.xml");

                        Line line = (Line) context.getBean("line");

                        line.draw();

            }

}

This is the class that needs to be executed.

 

Spring.xml

<?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">

                        <property name="pointA" ref = "point1"></property>

                         <property name="pointB" ref = "point2"></property>

               </bean>

              

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

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

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

               </bean>

              

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

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

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

               </bean>

</beans>

This is the bean definition file.

 

Inner Beans

Here the Point beans can be reused in other beans as well. If you want them to be used only for the line bean, you can make it inner to the Line bean, and you may also remove the id as it is not needed to refer to.

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

                        <property name="pointA">

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

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

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

                                    </bean>

                        </property>

                        <property name="pointB" ref="point2"></property>

            </bean>

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

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

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

            </bean>

I have made point1 as an inner bean for pointA property.

 

Name and Alias

You can also give a name or alias to a bean as:

<bean id="point2" class="com.javajee.spring.Point" name="point2bean">

Or

<alias name="point2" alias="point2beanalias"/>

 

The pointB ref attribute can now point to point2 or point2bean or point2beanalias, all giving the same results. This is because ref attribute can point to an id, name or alias.

Comments

We have two ways to reffer another beans in the spring application context configuration.

A. Using ref tag

B. Using idref tag

ref tag - Used to pass the bean to the calling class

idref tag - Used to pass the name (identifier - a string value) of the bean to the calling class

Here we have class Point.java and class Line.java

By using idref in application context configuration the code will be as followed.

<bean id="line" class="com.spring.io.Line">
        <property name="pointA" >
            <idref bean="point1"/>
        </property>
        <property name="pointB" ref="point2"></property>
    </bean>
    
    <bean id="point1" class="com.spring.io.Point">
        <property name="x" value="10"></property>
        <property name="y" value="10"></property>
    </bean>

By executing these lines we encounter an exception as: Failed to convert property value of type 'java.lang.String' to required type 'com.spring.io.Point' for property 'pointA';

Because we are trying to refer a type of Point with String type. idref is purely sending a String value.

So accept the String value sent by idref, we will create a variable of type String in class Line.java

private String beanName;

So now in spring.xml we make the following changes.

<bean id="line" class="com.spring.io.Line">
        <property name="pointA" ref="point1"></property>
        <property name="beanName">
            <idref bean="point1"/>
        </property>
    </bean>
    
    <bean id="point1" class="com.spring.io.Point">
        <property name="x" value="10"></property>
        <property name="y" value="10"></property>
    </bean>

So, main purpose of using idref tag is to validate the presence of bean with the name "point1" at deployment time. If bean is not existing then it throws an exception.

Was it useful?

Search the Web

Custom Search

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