Spring ListFactoryBean example

The ‘ListFactoryBean’ object provides developer a way to create a concrete List collection class (ArrayList and LinkedList) in Spring’s bean configuration file.

Example

Here’s a ListFactoryBean example, it will instantiate an ArrayList at runtime.

package com.mkyong.common;
 
import java.util.List;
 
public class Customer 
{
	private List lists;
 
	public List getLists() {
		return lists;
	}
 
	public void setLists(List lists) {
		this.lists = lists;
	}
 
	@Override
	public String toString() {
		return "Customer [lists=" + lists + "]" +
          	   " Type=[" + lists.getClass() + "]";
	}	
}

Spring’s bean configuration file.

<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-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer">
	<property name="lists">
	   <bean class="org.springframework.beans.factory.config.ListFactoryBean">
		<property name="targetListClass">
			<value>java.util.ArrayList</value>
		</property>
		<property name="sourceList">
			<list>
				<value>1</value>
				<value>2</value>
				<value>3</value>
			</list>
		</property>
	   </bean>
	</property>
</bean>
 
</beans>

Alternatively, you also can use the util schema and <util:list> to achieve the same thing.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer">
	<property name="lists">
		<util:list list-class="java.util.ArrayList">
			<value>1</value>
			<value>2</value>
			<value>3</value>
		</util:list>
	</property>
</bean>
 
</beans>

Remember to include the util schema, else you will hit the following error

Caused by: org.xml.sax.SAXParseException: 
The prefix "util" for element "util:list" is not bound.

Run it…

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
 
    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
 
    }
}

Ouput

Customer [lists=[1, 2, 3]] Type=[class java.util.ArrayList]

You have instantiated and injected a ArrayList into Customer’s lists property at runtime.

Spring – Collections (List, Set, Map, and Properties) example

In Spring framework, it’s allow to configuration the Collections type (List, Set, Map, and Properties) in Spring’s bean configuration file.

The major collection types are supported :

  • List – <list/>
  • Set – <set/>
  • Map – <map/>
  • Properties – <props/>

Example

A Customer object for the Spring’s collections type demonstration.

package com.mkyong.common;
 
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
 
public class Customer 
{
	private List<Object> lists;
	private Set<Object> sets;
	private Map<Object, Object> maps;
	private Properties pros;
 
	//getter and setter methods
 
	@Override
	public String toString() {
		return "Customer [lists=" + lists + ", maps=" + maps + ", 
                          pros=" + pros + ", sets=" + sets + "]";
	}
}

Here are a list of the collection type examples in Spring’s bean configuration file, the constant value is define by <value>, bean reference by <ref>, and inner bean definition by <bean>.

1. List example

	<property name="lists">
		<list>
			<value>1</value>
			<ref bean="PersonBean" />
			<bean class="com.mkyong.common.Person">
				<property name="name" value="mkyongList" />
				<property name="address" value="address" />
				<property name="age" value="28" />
			</bean>
		</list>
	</property>

2. Set example

	<property name="sets">
		<set>
			<value>1</value>
			<ref bean="PersonBean" />
			<bean class="com.mkyong.common.Person">
				<property name="name" value="mkyongSet" />
				<property name="address" value="address" />
				<property name="age" value="28" />
			</bean>	
		</set>
	</property>

3. Map example

	<property name="maps">
		<map>
			<entry>
				<key>
					<value>key 1</value>
				</key>
				<value>1</value>
			</entry>
			<entry>
				<key>
					<value>key 2</value>
				</key>
				<ref bean="PersonBean" />
			</entry>
			<entry>
				<key>
					<value>key 3</value>
				</key>
				<bean class="com.mkyong.common.Person">
					<property name="name" value="mkyongMap" />
					<property name="address" value="address" />
					<property name="age" value="28" />
				</bean>	
			</entry>
		</map>
	</property>

A shorted way

	<property name="maps">
		<map>
			<entry key="Key 1" value="1" />
			<entry key="Key 2" value-ref="PersonBean" />
			<entry key="Key 3">
				<bean class="com.mkyong.common.Person">
					<property name="name" value="mkyongMap" />
					<property name="address" value="address" />
					<property name="age" value="28" />
				</bean>
			</entry>
		</map>
	</property>

4. Properties example

	<property name="pros">
		<props>
			<prop key="admin">admin@nospam.com</prop>
		    <prop key="support">support@nospam.com</prop>
		</props>
	</property>

Full Spring’s bean configuration file.

<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-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer">
 
	<!-- java.util.List -->
	<property name="lists">
		<list>
			<value>1</value>
			<ref bean="PersonBean" />
			<bean class="com.mkyong.common.Person">
				<property name="name" value="mkyongList" />
				<property name="address" value="address" />
				<property name="age" value="28" />
			</bean>
		</list>
	</property>
 
	<!-- java.util.Set -->
	<property name="sets">
		<set>
			<value>1</value>
			<ref bean="PersonBean" />
			<bean class="com.mkyong.common.Person">
				<property name="name" value="mkyongSet" />
				<property name="address" value="address" />
				<property name="age" value="28" />
			</bean>	
		</set>
	</property>
 
	<!-- java.util.Map -->
	<property name="maps">
		<map>
			<entry key="Key 1" value="1" />
			<entry key="Key 2" value-ref="PersonBean" />
			<entry key="Key 3">
				<bean class="com.mkyong.common.Person">
					<property name="name" value="mkyongMap" />
					<property name="address" value="address" />
					<property name="age" value="28" />
				</bean>
			</entry>
		</map>
	</property>
 
	<!-- java.util.Properties -->
	<property name="pros">
	    <props>
	        <prop key="admin">admin@nospam.com</prop>
	        <prop key="support">support@nospam.com</prop>
	    </props>
	</property>
 
</bean>
 
<bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong1" />
	<property name="address" value="address 1" />
	<property name="age" value="28" />
</bean>
 
</beans>

Run it…

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
 
    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
 
    }
}

Output

Customer [
 
lists=[
1, 
Person [address=address 1, age=28, name=mkyong1], 
Person [address=address, age=28, name=mkyongList]
], 
 
maps={
key 1=1,
key 2=Person [address=address 1, age=28, name=mkyong1], 
key 3=Person [address=address, age=28, name=mkyongMap]
}, 
 
pros={admin=admin@nospam.com, support=support@nospam.com}, 
 
sets=[
1, 
Person [address=address 1, age=28, name=mkyong1], 
Person [address=address, age=28, name=mkyongSet]]
]
Spring – Bean Configuration Inheritance

In Spring, the inheritance is supported in bean configuration and it is quite useful for a bean sharing some common value or configurations. A child bean or inherited bean will inherit the bean configuration, properties and some attributes from the parent bean. In additional, the child beans are allow to override the inherited value.

Inheritance Example

Here’s a Customer class, let see how the inheritance work.

package com.mkyong.common;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
	private String Country;
 
	//getter and setter methods
 
	@Override
	public String toString() {
		return "Customer [Country=" + Country + ", action=" + action
				+ ", person=" + person + ", type=" + type + "]";
	}
 
}

Bean configuration file

<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-2.5.xsd">
 
	<bean id="BaseCustomerMalaysia" class="com.mkyong.common.Customer">
		<property name="country" value="Malaysia" />
	</bean>
 
	<bean id="CustomerBean" parent="BaseCustomerMalaysia">
		<property name="person" ref="PersonBean" />
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong1" />
		<property name="address" value="address 1" />
		<property name="age" value="28" />
	</bean>
 
</beans>

Above is a ‘BaseCustomerMalaysia’ bean contains a ‘Malaysia’ value for country property, and the ‘CustomerBean’ bean inherited this value from parent (‘BaseCustomerMalaysia’).

Run it

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
 
    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
 
    }
}

output

Customer [Country=Malaysia, action=buy, 
person=Person [address=address 1, age=28, name=mkyong1], type=1]

The ‘CustomerBean’ bean just inherited the country property from its parent (‘BaseCustomerMalaysia’).

Inheritance with abstract

In above example, the ‘BaseCustomerMalaysia’ is still able to instantiate.

Customer cust = (Customer)context.getBean("BaseCustomerMalaysia");

If you want to make this base bean as a template and not allow to instantiate it, you can add an abstract attribute in the <bean> element. For example

<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-2.5.xsd">
 
	<bean id="BaseCustomerMalaysia" class="com.mkyong.common.Customer" 
                 abstract="true">
 
		<property name="country" value="Malaysia" />
	</bean>
 
	<bean id="CustomerBean" parent="BaseCustomerMalaysia">
		<property name="person" ref="PersonBean" />
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong1" />
		<property name="address" value="address 1" />
		<property name="age" value="28" />
	</bean>
 
</beans>

Now, the ‘BaseCustomerMalaysia’ bean is a pure template for the inheritance only, if you try to instantiate it, you will encounter the following error message.

Customer cust = (Customer)context.getBean("BaseCustomerMalaysia");
org.springframework.beans.factory.BeanIsAbstractException: 
Error creating bean with name 'BaseCustomerMalaysia': 
Bean definition is abstract

Another Inheritance Example

The parent bean is not necessary to define the class attribute, often times, you may just need a common property for sharing. Here’s is an example

<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-2.5.xsd">
 
	<bean id="BaseCustomerMalaysia" abstract="true">
		<property name="country" value="Malaysia" />
	</bean>
 
	<bean id="CustomerBean" parent="BaseCustomerMalaysia" 
	    class="com.mkyong.common.Customer">
 
		<property name="person" ref="PersonBean" />
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong1" />
		<property name="address" value="address 1" />
		<property name="age" value="28" />
	</bean>
 
</beans>

In this case, the ‘BaseCustomerMalaysia’ bean is a pure template for sharing the country property only.

Overrride it

You can override the inherited value by specify the new value in the child bean. Let’s see this example

<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-2.5.xsd">
 
	<bean id="BaseCustomerMalaysia" class="com.mkyong.common.Customer" 
                abstract="true">
 
		<property name="country" value="Malaysia" />
	</bean>
 
	<bean id="CustomerBean" parent="BaseCustomerMalaysia">
	        <property name="country" value="Japan" />
		<property name="person" ref="PersonBean" />
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong1" />
		<property name="address" value="address 1" />
		<property name="age" value="28" />
	</bean>
 
</beans>

The ‘CustomerBean’ bean is just override the parent (‘BaseCustomerMalaysia’) country property, from ‘Malaysia’ to ‘Japan’.

Customer [Country=Japan, action=buy, 
person=Person [address=address 1, age=28, name=mkyong1], type=1]

Conclusion

The Spring bean configuration inheritance is very useful to avoid the repeated common value or configurations for multiple beans.

Spring – Auto-Wiring Beans with @Autowired annotation

The auto-wiring in the bean configuration file will wire all properties of a bean. In most cases, you may need wire a particular property only. In Spring 2.5, it’s greatly enhance on the auto-wiring feature, it’s possible to use @Autowired annotation to auto-wire bean on the setter method, constructor or a field. Moreover, it can wire on a particular property.

P.S The @Autowired annotation is auto-wire the bean by matching the data type.

Example

Here’s a customer and bean configuration file for the demonstration.

package com.mkyong.common;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
 
	//getter and setter method
 
}
<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-2.5.xsd">
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address 123" />
		<property name="age" value="28" />
	</bean>
 
</beans>

Enable the @Autowired

To enable the @Autowired, you have to register an ‘AutowiredAnnotationBeanPostProcessor’. You can register it in two ways.

1. Include <context:annotation-config />

Add Spring context and <context:annotation-config /> in bean configuration file.

<beans 
...
xmlns:context="http://www.springframework.org/schema/context"
...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
...
<context:annotation-config />
...
</beans>
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
<context:annotation-config />
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>
 
</beans>

2. Include AutowiredAnnotationBeanPostProcessor

Include ‘AutowiredAnnotationBeanPostProcessor’ directly in bean configuration file.

<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-2.5.xsd">
 
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>
 
</beans>

@Autowired annotation examples

The @Autowired annotation can be applied to the setter method, constructor or a field

1. @Autowired setter method

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
 
	@Autowired
	public void setPerson(Person person) {
		this.person = person;
	}
}

2. @Autowired construtor

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
 
	@Autowired
	public Customer(Person person) {
		this.person = person;
	}
}

3. @Autowired field

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Customer 
{
	@Autowired
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
}

The above examples will auto-wire ‘PersonBean’ into the Customer person property at runtime.

Run it

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
 
    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
 
    }
}

Output

Customer [action=buy, 
person=Person [address=address 123, age=28, name=mkyong], type=1]

@Autowired with dependency checking

By default, the @Autowired will do the dependency checking to make sure the properties has been wired. When Spring can’t find a matching bean to wire, it will throw an exception. You can disable this checking feature by setting the required attribute of @Autowired to false.

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Customer 
{
	@Autowired(required=false)
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
}

In the above example, if the Spring can’t find a matching bean, it will leave the person property unset.

@Autowired with @Qualifier

In last article, auto-wiring beans in bean configuration file, i did mention about more than one beans matching problem, however it did happened to the @Autowired annotation as well. When there are more than one beans are matching, Spring will throw an exception.

Spring did created a new annotation named @Qualifier to solve this problem. By using @Qualifier, you can specify a bean’s name to wire into the bean property.

@Qualifier Example

A bean configuration file with two person beans.

<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
<context:annotation-config />
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean1" class="com.mkyong.common.Person">
		<property name="name" value="mkyong1" />
		<property name="address" value="address 1" />
		<property name="age" value="28" />
	</bean>
 
	<bean id="PersonBean2" class="com.mkyong.common.Person">
		<property name="name" value="mkyong2" />
		<property name="address" value="address 2" />
		<property name="age" value="28" />
	</bean>
 
</beans>

Wire “PersonBean1″ into the Customer person property.

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
public class Customer 
{
	@Autowired
	@Qualifier("PersonBean1")
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
}

Conclusion

The @Autowired annotation is highly flexible and powerful, and definitely better than the limited function supported by the auto-wiring feature in bean configuration file.

Spring – Auto-Wiring Beans in XML

In Spring framework, you can wire your beans automatically with auto-wiring feature. To enable it, you need to specify the auto-wiring mode in the autowire attribute of <bean>.

Auto-wiring modes

In Spring, 5 Auto-wiring modes are supported.

  • no – No auto-wiring.
  • byName – Auto-wire a bean whose the name is same as the property.
  • byType – Auto-wire a bean whose data type is compatible with the property.
  • constructor – Auto-wire a bean whose date type is compatible with the property constructor argument.
  • autodetect – If a default constructor with no argument is found, it will auto-wire by data type. Otherwise, it will auto-wire by constructor.

In case of any ambiguity in ‘byType’ or ‘constructor’ mode, an UnsatisfiedDependencyException will be thrown.

P.S The default mode is ‘no’.

Example

A Customer and Person object for the demonstration.

package com.mkyong.common;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
 
	//getter and setter methods
 
       @Override
	public String toString() {
		return "Customer [action=" + action + ", person=" + person + 
                          ",type=" + type + "]";
	}
 
}
package com.mkyong.common;
 
public class Person 
{
	private String name;
	private String address;
	private int age;
 
	//getter and setter methods	
}

1. ‘no’ auto-Wiring mode

This is the default mode, you have to wire your bean explicitly by using the ‘ref’ attribute.

<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-2.5.xsd">
 
 <bean id="CustomerBean" class="com.mkyong.common.Customer">
        <property name="person" ref="PersonBean" />
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

2. ‘byName’ auto-Wiring mode

It will auto-wire a bean whose name is same as the property.

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="byName">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Run it

Customer [action=buy, person=null, type=1]

You will notice that the person property is not auto-wire, the person is still ‘null’, this is because the bean name ‘PersonBean’ is mismatch, it should be ‘person’. In ‘byName’ mode, the name of the auto-wire bean and the property name have to be exactly same (case sensitive as well).

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="byName">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="person" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Run it again

Customer [action=buy, 
person=Person [address=address 123, age=28, name=mkyong], type=1]
Problem

In most cases, it is not practical to always make the name of the target bean the same as your property. In the end, you will always have a mixture of explicit wiring and auto-wiring environment.

3. ‘byType’ auto-Wiring mode

It will auto-wire a bean whose data type is same as the property.

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="byType">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="person" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Run it

Customer [action=buy, 
person=Person [address=address 123, age=28, name=mkyong], type=1]
Problem

Assume you have two person’s Beans as following :

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="byType">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean1" class="com.mkyong.common.Person">
	<property name="name" value="mkyong1" />
	<property name="address" value="address 1" />
	<property name="age" value="28" />
  </bean>
 
  <bean id="PersonBean2" class="com.mkyong.common.Person">
	<property name="name" value="mkyong2" />
	<property name="address" value="address 2" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Run it, you will hit the following error message

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No unique bean of type [com.mkyong.common.Person] is defined: 
expected single matching bean but found 2: [PersonBean1, PersonBean2]

The problem is sometimes there will be more than one beans are match with ‘byType’ criteria. In this case, Spring will throw an UnsatisfiedDependencyException exception.

4. ‘constructor’ auto-Wiring mode

It will auto-wire a bean whose date type is compatible with the property constructor argument. In this case, person bean will inject via Customer’s constructor automatically.

- Add a constructor to Customer class

package com.mkyong.common;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
 
	public Customer(Person person) {
		this.person = person;
	}
        //getter and setter method
	@Override
	public String toString() {
		return "Customer [action=" + action + ", person=" + person + 
                         ", type=" + type + "]";
	}
}
<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="constructor">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Run it

Customer [action=buy, 
person=Person [address=address 123, age=28, name=mkyong], type=1]
Problem

The ‘constructor’ mode is facing the same problem with ‘byType’ auto-wire mode, if more than one beans are matched, Spring will throw an UnsatisfiedDependencyException exception as well. In addition, multiple constructors in a class may causing the ambiguity in constructor argument matching, in this case you will spend more time on resolving the issue.

5. ‘autodetect’ auto-Wiring mode

If a default constructor with no argument is found, it will auto-wire by data type. Otherwise, it will auto-wire by constructor.

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" autowire="autodetect">
	<property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>
Problem

It has the same problem with ‘byType’ and ‘constructor’, the worst is you may need to find out which mode is execute now.

Good Practice

It’s always good to combine the ‘auto-wire’ and ‘dependency-check’ feature together to make sure the property is auto-wire successfully.

<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-2.5.xsd">
 
  <bean id="CustomerBean" class="com.mkyong.common.Customer" 
	autowire="autodetect" dependency-check="objects">
 
        <property name="action" value="buy" />
	<property name="type" value="1" />
  </bean>
 
  <bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address 123" />
	<property name="age" value="28" />
  </bean>
 
</beans>

Conclusion

In my opinion, this Spring ‘auto-wiring’ feature will reduce the readability of your bean configuration, and you even do not know which beans will wired from the bean configuration file, you are totally out of control of what will happened.

In practice, i recommend applying ‘auto-wiring’ only in small and simple component dependencies applications.

P.S The @Autowired annotation is more flexible and recommended than the auto-wiring in bean configuration file. Read this article – Spring – Auto-Wiring Beans with @Autowired annotation.