Autowired
annotation is used to auowire beans. In the following example, Address bean is
auowired in Employee class.
Step 1
: Create new
maven project “spring_tuorial”. Project structure looks like below.
Step 2
: Update
“pom.xml” file for maven dependencies.
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>spring_tutorial</groupId> <artifactId>spring_tutorial</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>spring_tutorial</name> <description>spring_tutorial</description> <properties> <org.springframework-version>4.1.5.RELEASE</org.springframework-version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> </dependency> </dependencies> </project>
Step
3: Create new
package “com.springtutorial.model” under “src/main/java”.
Step
4: Create Address
class under the package “com.springtutorial.model”.
package com.springtutorial.model; public class Address { private String street; private String city; private String state; private String country; private String pin; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getPin() { return pin; } public void setPin(String pin) { this.pin = pin; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Address [street=").append(street).append(", city=").append(city) .append(", state=").append(state).append(", country=").append(country).append(", pin=") .append(pin).append("]"); return builder.toString(); } }
Step
5: Create
“Employee” class under the package “com.springtutorial.model”.
package com.springtutorial.model; import org.springframework.beans.factory.annotation.Autowired; public class Employee { private String firstName; private String lastName; private int id; @Autowired Address address; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", id=" + id + ", address=" + address + "]"; } }
@Autowired
Address address;
address
property is autowired, this property is initialized by spring container
automatically.
Step
6: Create
“spring.xml” file in “src/main/resources”.
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" 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="employee" class="com.springtutorial.model.Employee"> <property name="firstName" value="Hari Krishna" /> <property name="lastName" value="Gurram" /> <property name="id" value="553" /> </bean> <bean id="tempAddress" class="com.springtutorial.model.Address"> <property name="street" value="Marthalli" /> <property name="city" value="Bangalore" /> <property name="state" value="Karnataka" /> <property name="country" value="India" /> <property name="pin" value="560037" /> </bean> </beans>
"spring.xml"
is used to assign unique IDs to different beans, to control the creation of
objects with different values. You have to make sure that “spring.xml” file is
available in CLASSPATH and use the same name in main application while creating
application context as shown in Main.java file.
Step 6
: Create package
“com.springtutorial.main” under “src/main/java”.
Step 7
: Create Main
class under package “com.springtutorial.main”.
package com.springtutorial.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.springtutorial.model.Employee; public class Main { public static void main(String args[]) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Employee emp = (Employee) context.getBean("employee"); System.out.println(emp); ((ClassPathXmlApplicationContext) context).close(); } }
Step
8: Run
Main.java,you will get error like below.
Apr 02, 2015 9:10:42 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1509f8b: startup date [Thu Apr 02 21:10:42 IST 2015]; root of context hierarchy Apr 02, 2015 9:10:42 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring.xml] Employee [firstName=Hari Krishna, lastName=Gurram, id=553, address=Address [street=Marthalli, city=Bangalore, state=Karnataka, country=India, pin=560037]] Apr 02, 2015 9:10:42 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1509f8b: startup date [Thu Apr 02 21:10:42 IST 2015]; root of context hierarchy
Final
project structure looks like below.
What
if spring.xml defined with two address beans?
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" 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="employee" class="com.springtutorial.model.Employee"> <property name="firstName" value="Hari Krishna" /> <property name="lastName" value="Gurram" /> <property name="id" value="553" /> </bean> <bean id="tempAddress" class="com.springtutorial.model.Address"> <property name="street" value="Marthalli" /> <property name="city" value="Bangalore" /> <property name="state" value="Karnataka" /> <property name="country" value="India" /> <property name="pin" value="560037" /> </bean> <bean id="permAddress" class="com.springtutorial.model.Address"> <property name="street" value="Ongole" /> <property name="city" value="Ongole" /> <property name="state" value="Andhra Pradesh" /> <property name="country" value="India" /> <property name="pin" value="560037" /> </bean> </beans>
As you
observe i defined two beans( tempAddress, permAddress) of type Address in
spring.xml. Run main.java, you will get error like below.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.springtutorial.model.Address com.springtutorial.model.Employee.address; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.springtutorial.model.Address] is defined: expected single matching bean but found 2: tempAddress,permAddress
Since
there are two beans defined for Address class, Spring don't know which one to
assign.
How to
solve this problem?
a.
Autowire by name
Change
the name of the Address property in Employee class to match one of bean id in
spring.xml.
package com.springtutorial.model; import org.springframework.beans.factory.annotation.Autowired; public class Employee { private String firstName; private String lastName; private int id; @Autowired Address tempAddress; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Address getAddress() { return tempAddress; } public void setAddress(Address address) { this.tempAddress = address; } @Override public String toString() { return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", id=" + id + ", address=" + tempAddress + "]"; } }
In the
above class, i am using Address name as tempAddress, which matched to one of
the Address bean id defined in spring.xml.
b.
Using Qualifier
@Qualifier
annotation along with @Autowired is used to remove the confusion by specifying
which exact bean will be wired.
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" 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="employee" class="com.springtutorial.model.Employee"> <property name="firstName" value="Hari Krishna" /> <property name="lastName" value="Gurram" /> <property name="id" value="553" /> </bean> <bean id="tempAddress" class="com.springtutorial.model.Address"> <qualifier value="temporaryAddress" /> <property name="street" value="Marthalli" /> <property name="city" value="Bangalore" /> <property name="state" value="Karnataka" /> <property name="country" value="India" /> <property name="pin" value="560037" /> </bean> <bean id="permAddress" class="com.springtutorial.model.Address"> <property name="street" value="Ongole" /> <property name="city" value="Ongole" /> <property name="state" value="Andhra Pradesh" /> <property name="country" value="India" /> <property name="pin" value="560037" /> </bean> </beans>
<bean
id="tempAddress"
class="com.springtutorial.model.Address">
<qualifier
value="temporaryAddress" />
<property
name="street" value="Marthalli" />
<property
name="city" value="Bangalore" />
<property
name="state" value="Karnataka" />
<property
name="country" value="India" />
<property
name="pin" value="560037" />
</bean>
For bean
id “tempAddress”, qualifier given as “ temporaryAddress”.
Employee.java
package com.springtutorial.model; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class Employee { private String firstName; private String lastName; private int id; @Autowired @Qualifier("temporaryAddress") Address address; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", id=" + id + ", address=" + address + "]"; } }
@Autowired
@Qualifier("temporaryAddress")
Address address;
Above
statement makes sure, bean with the qualifier “temporaryAddress” is assigned to
property address.
No comments:
Post a Comment