IoC的自动装载(Autowire)
IoC负责创建对象,DI负责完成对象的依赖注入,它是通过配置property标签的ref属性来完成。
同时Spring提供了另外一种更加简单的依赖注入方式,也就是自动装载,不需要手动配置property,IoC会自动选择bean 并完成注入。
自动装载有两种方式:
- byName:通过属性名自动装载。
- byType:通过属性的数据类型完成自动装载。
首先我们创建两个类Student和Address。
package com.exambner.ioc;public class Student { private long id; private String name; private int age; private Address address; public Student() { System.out.println("创建了Student对象"); } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", address=" + address + '}'; } }
package com.exambner.ioc; public class Address { private long id; private String address; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "id=" + id + ", address='" + address + '\'' + '}'; } }
配置文件:
<bean id="address" class="com.exambner.ioc.Address"> <property name="id" value="1"></property> <property name="address" value="南京"></property> </bean> <bean id="student" class="com.exambner.ioc.Student"> <property name="id" value="1"></property> <property name="name" value="小明"></property> <property name="age" value="18"></property> <property name="address" ref="address"></property> </bean>
这时我们在注入address属性时,需要通过ref注入对应的id为student的bean。这个时候使我们手动去做的bean的装载操作,也就是依赖注入。
获取bean student的信息:
public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Student student = (Student) applicationContext.getBean("student"); System.out.println(student); }
Student{id=1, name='小明', age=18, address=Address{id=1, address='南京'}}
我们也可以使用自动装载来完成自动装载操作。
1、我们可以使用byName的方式来完成自动装载,它是通过bean的名称来完成的自动装载。
<bean id="address" class="com.exambner.ioc.Address"> <property name="id" value="1"></property> <property name="address" value="南京"></property> </bean> <bean id="student" class="com.exambner.ioc.Student" autowire="byName"> <property name="id" value="1"></property> <property name="name" value="小明"></property> <property name="age" value="18"></property> </bean>
也就是通过类中的字段名称匹配对应的bean。
private Address address;
Student{id=1, name='小明', age=18, address=Address{id=1, address='南京'}}
如果这里我们把address字段更改为addresses,就无法完成自动装配的操作,因为装不到id为addresses的bean。
private Address addresses;
Student{id=1, name='小明', age=18, addresses=null}
2、这里我们也可以通过byType的方式来完成自动装配。
<bean id="address" class="com.exambner.ioc.Address"> <property name="id" value="1"></property> <property name="address" value="南京"></property> </bean> <bean id="student" class="com.exambner.ioc.Student" autowire="byType"> <property name="id" value="1"></property> <property name="name" value="小明"></property> <property name="age" value="18"></property> </bean>
这个时候自动装配时就不再考虑字段名称了,而是通过字段类型来进行匹配bean中的class属性。
Student{id=1, name='小明', age=18, addresses=Address{id=1, address='南京'}}
但是加入我们存在相同类型的两个bean时,通过byName就会出现问题。
<bean id="address" class="com.exambner.ioc.Address"> <property name="id" value="1"></property> <property name="address" value="南京"></property> </bean> <bean id="address1" class="com.exambner.ioc.Address"> <property name="id" value="2"></property> <property name="address" value="上海"></property> </bean> <bean id="student" class="com.exambner.ioc.Student" autowire="byType"> <property name="id" value="1"></property> <property name="name" value="小明"></property> <property name="age" value="18"></property> </bean>
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'student' defined in class path resource [spring.xml]: Unsatisfied dependency expressed through bean property 'addresses';
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.exambner.ioc.Address' available: expected single matching bean but found 2: address,address1
会提示我们找到了两个类型为Address的bean,spring不能确认我们需要的是哪一个bean,所以会提示异常。

浙公网安备 33010602011771号