Spring autowire Examples

0

In this article, we will look into spring’s auto-wiring ability. I will show you examples of auto-wiring by type, name and the constructor.
auto-wiring is done using one of the below strategies.

  1. byType
  2. byName
  3. constructor
  4. no

You can either set the default-autowiring attribute at beans level or use the autowiring at bean level to set the auto-wiring strategy to one one of the above mentioned strategies.

Dependencies

Add the following dependencies:

  1. spring-core
  2. spring-context
  3. spring-beans

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javarticles.jdbc.datasource</groupId>
	<artifactId>springdatasource</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>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>3.2.3.RELEASE</spring.version>
	</properties>

</project>

Auto-Wiring By Type

In testBean definition, we have set autowire to byType.

autowireByTypeContext.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.xsd">

	<bean id="testBean" class="com.javarticles.spring.TestBean" autowire="byType">
		<constructor-arg type="java.lang.String" value="A" />
	</bean>
	<bean id="type1" class="com.javarticles.spring.Type1"/>
	<bean id="type2ByName" class="com.javarticles.spring.Type2"/>

</beans>

TestBean has member variables type1ByType and type2ByName of type Type1 and Type2. If you notice, we have not explicitly set the properties of of these member variables in the bean definition of TestBean. We want spring to figure out automatically and auto-wire for us using the type as the matching strategy.

TestBean:

package com.javarticles.spring;

public class TestBean {
    private String value;
    private Type1 type1ByType;
    private Type2 type2ByName;
    
    public TestBean(){}
    
    public TestBean(String value) {
        this.value = value;
    }
    
    public TestBean(Type1 type1, Type2 type2) {
        type1ByType = type1;
        type2ByName = type2;
    }
    
    public void setValue(String value) {
        this.value = value;
    }

    public Type1 getType1ByType() {
        return type1ByType;
    }

    public void setType1ByType(Type1 type1ByType) {
        this.type1ByType = type1ByType;
    }

    public Type2 getType2ByName() {
        return type2ByName;
    }

    public void setType2ByName(Type2 type2ByName) {
        this.type2ByName = type2ByName;
    }

    public String getValue() {
        return value;
    }       
}

Type1:

package com.javarticles.spring;

public class Type1 {

    public String toString() {
        return "Type1";
    }
}

Type2:

package com.javarticles.spring;

public class Type2 {
    public String toString() {
        return "Type2";
    }
}

AutowireByTypeExample:

package com.javarticles.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AutowireByTypeExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "autowireByTypeContext.xml");
        try {
            TestBean testBean = (TestBean) context.getBean("testBean");
            System.out.println("testBean.type1's value: " + testBean.getType1ByType());
            System.out.println("testBean.type2's value: " + testBean.getType2ByName());
        } finally {
            context.close();
        } 
    }
}

You can see spring managed to find the properties by type and set them to the bean.

Output:

testBean.type1's value: Type1
testBean.type2's value: Type2

Auto-Wiring By Name

In this example, spring will use the name of the member variable to find the respective beans and wire them to the TestBean. Since we have a bean for type2ByName, it will manage to set type2ByName member variable but since there is no bean for type1ByType it will not be able to set the bean and TestBean.getType1ByType() should return us null.

autowireByNameContext.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.xsd">

	<bean id="testBean" class="com.javarticles.spring.TestBean" autowire="byName">
		<constructor-arg type="java.lang.String" value="A" />
	</bean>
	<bean id="type1" class="com.javarticles.spring.Type1"/>
	<bean id="type2ByName" class="com.javarticles.spring.Type2"/>
	
</beans>

We will explicitly register a bean of name type1ByType so that the second time when we load the context, it is going to set both the properties.

AutowireByNameExample:

package com.javarticles.spring;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AutowireByNameExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "autowireByNameContext.xml");
        try {
            TestBean testBean = (TestBean) context.getBean("testBean");
            System.out.println("testBean.type1ByType: " + testBean.getType1ByType());
            System.out.println("testBean.type2ByName: " + testBean.getType2ByName());
            
            RootBeanDefinition bd = new RootBeanDefinition(Type1.class);
            DefaultListableBeanFactory lbf = (DefaultListableBeanFactory) context.getBeanFactory();
            DefaultListableBeanFactory parentLbf = new DefaultListableBeanFactory();
            System.out.println("Register new bean type1ByType");
            parentLbf.registerBeanDefinition("type1ByType", bd);   
            lbf.setParentBeanFactory(parentLbf);            
            lbf.destroySingleton("testBean");
            
            System.out.println("Get testBean");
            testBean = (TestBean) context.getBean("testBean");
            System.out.println("testBean.type1ByType: " + testBean.getType1ByType());
        } finally {
            context.close();
        } 
    }
}

Output:

testBean.type1ByType: null
testBean.type2ByName: Type2
Register new bean type1ByType
Get testBean
testBean.type1ByType: Type1

Auto-Wiring By Constructor

Just like ByType auto-wiring, spring manages to find the beans for type1 and type2 parameters and set them.

    public TestBean(Type1 type1, Type2 type2) {
        type1ByType = type1;
        type2ByName = type2;
    }

autowireConstructorContext.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.xsd">

	<bean id="testBean" class="com.javarticles.spring.TestBean" autowire="constructor">
		<property name="value" value="A" />
	</bean>
	<bean id="type1" class="com.javarticles.spring.Type1"/>
	<bean id="type2ByName" class="com.javarticles.spring.Type2"/>
</beans>

AutowireConstructorExample:

package com.javarticles.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AutowireConstructorExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "autowireConstructorContext.xml");
        try {
            TestBean testBean = (TestBean) context.getBean("testBean");
            System.out.println("testBean.type1's value: " + testBean.getType1ByType());
            System.out.println("testBean.type2's value: " + testBean.getType2ByName());
        } finally {
            context.close();
        } 
    }
}

Output:

testBean.type1's value: Type1
testBean.type2's value: Type2

Default Auto-wiring

The default-autowire attribute is set to byName so the strategy applies on both testBean1 and testBean2.

defaultAutowireContext.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.xsd"
	default-autowire="byName">

	<bean id="testBean1" class="com.javarticles.spring.TestBean">
		<constructor-arg type="java.lang.String" value="A" />
	</bean>
    <bean id="testBean2" class="com.javarticles.spring.TestBean">
		<constructor-arg type="java.lang.String" value="B" />
	</bean>
	<bean id="type1ByType" class="com.javarticles.spring.Type1"/>
	<bean id="type2ByName" class="com.javarticles.spring.Type2"/>
</beans>

DefaultAutowireExample:

package com.javarticles.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DefaultAutowireExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "defaultAutowireContext.xml");
        try {
            TestBean testBean1 = (TestBean) context.getBean("testBean1");
            System.out.println("testBean1.type1's value: " + testBean1.getType1ByType());
            System.out.println("testBean1.type2's value: " + testBean1.getType2ByName());
            
            TestBean testBean2 = (TestBean) context.getBean("testBean2");
            System.out.println("testBean2.type1's value: " + testBean2.getType1ByType());
            System.out.println("testBean2.type2's value: " + testBean2.getType2ByName());
        } finally {
            context.close();
        }     
    }
}

Output:

testBean1.type1's value: Type1
testBean1.type2's value: Type2
testBean2.type1's value: Type1
testBean2.type2's value: Type2

Override default Auto-Wiring to ‘No’

One can override default-autowire attribute using autowire attribute at bean level. We set the value to no.

noAutoWiringContxt.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.xsd"
	default-autowire="byType">

	<bean id="testBean" class="com.javarticles.spring.TestBean" autowire="no">
		<constructor-arg type="java.lang.String" value="A" />
	</bean>
	<bean id="type1" class="com.javarticles.spring.Type1"/>
	<bean id="type2ByName" class="com.javarticles.spring.Type2"/>
</beans>

NoAutowireExample:

package com.javarticles.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class NoAutowireExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "noAutowireContext.xml");
        try {
            TestBean testBean = (TestBean) context.getBean("testBean");
            System.out.println("testBean.type1's value: " + testBean.getType1ByType());
            System.out.println("testBean.type2's value: " + testBean.getType2ByName());
        } finally {
            context.close();
        }        
    }
}

Output:

testBean.type1's value: null
testBean.type2's value: null

Download the source code

This was an example about spring’s auto-wiring attributes. I showed you different strategies of auto-wiring. You can download the source code here: springAutowireExample.zip

Share.

Comments are closed.