Autowire using Annotations

1)Instead of using autowiring feature in spring config file, we can use autowiring in the bean class itself.
In the config file we will just define the bean but we will autowire them in the class directly.
It reduces the xml coding.
Lets see how can we do it in spring.
In order to support this feature , we need to tell spring container that we are going to use this feature
That can be told by adding below tag in the spring config file

1
<context:annotation-config />
<context:annotation-config />

Now spring understood that wiring beans happens with annotations.
what are those annotations ?
@Autowired -> Spring’s annotation
@Inject -> from JSR 330
@Resource -> from JSR 250

@Autowired
This annotation does the autowiring by Type and it can be used on any of the below options
1)constructor
2)setter method
3)any method
4)property

Lets take the below example and will go through each option of autowiring

Person.java

1
2
3
4
5
6
7
8
9
10
11
package com.kb.autowiringAnnotation;
 
public class Person {
    Car car;
    
 
    public Car getCar() {
return car;
    }
    
}
package com.kb.autowiringAnnotation;

public class Person {
	Car car;
	

	public Car getCar() {
return car;
	}
	
}

Car.java

1
2
3
4
5
6
package com.kb.autowiringAnnotation;
 
 
public class Car {
    
}
package com.kb.autowiringAnnotation;


public class Car {
	
}

beans.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id = "person" class ="com.kb.autowiringAnnotation.Person"/>
<bean id="car" class="com.kb.autowiringAnnotation.Car"/>
</beans>
<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id = "person" class ="com.kb.autowiringAnnotation.Person"/>
<bean id="car" class="com.kb.autowiringAnnotation.Car"/>
</beans>

Now if we look at beans.xml file carefully, there is no wiring between Person and Car bean is specified.
Now to achieve this we have to use autowired annotation in any of the 4 ways
1)Constrcutor
Modify the Person class as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Person {
    Car car;
    
    @Autowired
    public Person(Car car) {
        this.car=car;
    }
 
    public Car getCar() {
        return car;
    }
    
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
	Car car;
	
	@Autowired
	public Person(Car car) {
		this.car=car;
	}

	public Car getCar() {
		return car;
	}
	
}

That’s it, now Person’s constructor is taking Car type as parameter hence autowiring annotation searches for car type bean in config file and hence it injects it.
2)Setter method -> autowiring is specified on setter method
Modify the Person class as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Person {
    Car car;
    
    public Car getCar() {
        return car;
    }
 
    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }
    
    
    
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
	Car car;
	
	public Car getCar() {
		return car;
	}

	@Autowired
	public void setCar(Car car) {
		this.car = car;
	}
	
	
	
}

Now autowiring looks for type of the bean specified inside setter method , it is car type and is available inside beans.xml and hence injects it
3)Any method
Autowiring can be done on any method where it searches for the type of the bean specified in the method’s parameter.
So type of parameter of a method should be available inside beans.xml
Modify Person class as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Person {
    Car car;
    
    public Car getCar() {
        return car;
    }
 
    @Autowired
    public void setCarCustom(Car car) {
        this.car = car;
    }
    
    
    
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
	Car car;
	
	public Car getCar() {
		return car;
	}

	@Autowired
	public void setCarCustom(Car car) {
		this.car = car;
	}
	
	
	
}

setCarCustom(Car car) method takes Car type as parameter and Car type bean is available in beans.xml
hence injects it.

4)Property
Autowiring can be done even simpler by just adding it on property, no constructor , no setter , no method is required.
See its power below
Modify Person class as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Person {
    
    @Autowired
    Car car;
    
    public Car getCar() {
        return car;
    }
 
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
	
	@Autowired
	Car car;
	
	public Car getCar() {
		return car;
	}

}

Autowire looks for Car type inside beans.xml and its available hence injects it.

Now all the autowire strategies are with the byType of autowire.

Lets see the problem with byType autowiring and its resolution

Now assume we have 2 beans for Car inside beans.xml car1 and car2 as below

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id = "person" class ="com.kb.autowiringAnnotation.Person"/>
<bean id="car1" class="com.kb.autowiringAnnotation.Car"/>
<bean id="car2" class="com.kb.autowiringAnnotation.Car"/>
</beans>
<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id = "person" class ="com.kb.autowiringAnnotation.Person"/>
<bean id="car1" class="com.kb.autowiringAnnotation.Car"/>
<bean id="car2" class="com.kb.autowiringAnnotation.Car"/>
</beans>

car.java

1
2
3
4
5
package com.kb.autowiringAnnotation;
 
public class Car {
 
}
package com.kb.autowiringAnnotation;

public class Car {

}

Now we autowire Car inside Person as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Person {
    
    @Autowired
    Car car;
    
    public Car getCar() {
        return car;
    }
 
 
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
	
	@Autowired
	Car car;
	
	public Car getCar() {
		return car;
	}


}

Client.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kb.autowiringAnnotation;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Client {
 
    public static void main(String[] args) {
        Person per;
        ApplicationContext  applicationContext = new ClassPathXmlApplicationContext("com/kb/autowiringAnnotation/beans.xml");
         per = (Person)applicationContext.getBean("person");
        System.out.println("person's car is "+per.getCar());
        
    }
    
}
package com.kb.autowiringAnnotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

	public static void main(String[] args) {
		Person per;
		ApplicationContext  applicationContext = new ClassPathXmlApplicationContext("com/kb/autowiringAnnotation/beans.xml");
		 per = (Person)applicationContext.getBean("person");
		System.out.println("person's car is "+per.getCar());
		
	}
	
}

Now running our client gives us the below exception

org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.kb.autowiringAnnotation.Car com.kb.autowiringAnnotation.Person.car; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.kb.autowiringAnnotation.Car] is defined: expected single matching bean but found 2: car1,car2

it clearly says autowiring is trying to do wiring by Type that means it is looking for Car type inside beans.xml but 2 beans with the same type are available.
which one it has to inject ?
Ambiguity exception.
So for autowire by type we should have only one bean of that type in the spring config file.

If we remove bean definition for car2 inside beans.xml file client runs happily without any exception and injects car1 into person.

But I need to define 2 beans of the same type and I want to use first one for wiring with Person and I want to use 2nd one to wire with some other class.
How to resolve this ?
Yes autowiring by name can be used but @autowired provides flexibility to specify the autowire by name using one more annotation @Qualifier.

Lets see with example
Modify the above Person class as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kb.autowiringAnnotation;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
public class Person {
    
    @Autowired
    @Qualifier("car1")
    Car car;
    
    public Car getCar() {
        return car;
    }
 
 
}
package com.kb.autowiringAnnotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Person {
	
	@Autowired
	@Qualifier("car1")
	Car car;
	
	public Car getCar() {
		return car;
	}


}

Now run the client , it runs successfully and injects first car bean.
@Qualifier takes String as its argument and it tries to find a match of that string as a qualifier bean or bean id inside spring config file.
Car1 is available as a bean id for first car bean definition hence it injects without any ambiguity.

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on