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,所以会提示异常。

 

posted @ 2023-01-05 03:11  Amireux-126  阅读(258)  评论(0)    收藏  举报