Spring笔记:bean的自动装配

装配就是指为对象的属性赋值,除了在xml文件中使用property标签显式赋值,还有其他的方式进行属性的自动赋值(装配)。

1. 使用bean标签的autowire属性自动装配。

bean标签的autowire属性常用的值有byName和byType,也代表了两种不同的自动装配方式。autowire为byName时,会根据对象的属性名去查找有没有相同名称的bean,因此这种方式需要保证xml中对应的bean是唯一的。byType会根据属性的类型去查找对应的bean,这种方式必须保证xml中该类型的对象只有一个,而且就算对应的bean标签没有设置id值,也能找到进行装配。以下是使用byName进行自动装配的示例:

Cat类:

package com.yun.pojo;

public class Cat {
    public void shout(){
        System.out.println("I'm a Cat!");
    }
}

Dog类:

package com.yun.pojo;

public class Dog {
    public void shout(){
        System.out.println("I'm a Dog!");
    }
}

Person类:

package com.yun.pojo;

public class Person {
    private String name;
    private Dog dog;
    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="cat" class="com.yun.pojo.Cat"/>
    <bean id="dog" class="com.yun.pojo.Dog"/>
    <!-- 配置了autowire="byName"之后,Spring会根据属性名自动寻找id名称相同的bean进行关联 -->
    <bean id="person" class="com.yun.pojo.Person" autowire="byName">
        <property name="name" value="zhangsan"/>
<!-- 以下是使用property标签进行赋值的方式,使用了autowire自动装配之后,就不需要配置对应的property标签了 -->
<!--        <property name="cat" ref="cat"/>-->
<!--        <property name="dog" ref="dog"/>-->
    </bean>
</beans>

测试:

import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = context.getBean("person", Person.class);
        person.getCat().shout();
        person.getDog().shout();
    }
}

2. 使用注解进行自动装配

我先把示例中会用到的基础的类列出来。

Cat类:

package com.yun.pojo;

public class Cat {
    public void shout(){
        System.out.println("I'm a Cat!");
    }
}

Dog类:

package com.yun.pojo;

public class Dog {
    public void shout(){
        System.out.println("I'm a Dog!");
    }
}

测试类:

import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = context.getBean("person", Person.class);
        person.getCat().shout();
        person.getDog().shout();
    }
}

2.1 @Autowired

这个注解可以添加到类属性上,通常来讲,被注解的属性是另一个bean,那么属性名和bean的id值应该是一致的,这种方式其实就是byName和byType的结合。另外, @Autowired 注解可以传入参数, @Autowired(required = false) 表示这个属性可以为null。使用这个注解需要在xml中添加的扩展有:

  • xmlns:context="http://www.springframework.org/schema/context"
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd
  • <context:annotation-config/>

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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 这个扩展以及上面的三个扩展千万别忘了,不然注解没法生效 -->
    <context:annotation-config/>

    <bean id="cat" class="com.yun.pojo.Cat"/>
    <bean id="dog" class="com.yun.pojo.Dog"/>
    <bean id="person" class="com.yun.pojo.Person"/>
</beans>

Person类:

package com.yun.pojo;

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

public class Person {
    private String name;
    @Autowired  // 注解的属性名需要和bean的id保持一致
    private Dog dog;
    @Autowired  // @Autowired(required = false),表示这个属性可以为null。
    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

2.2 @Nullable

表示被注解的属性可以为null。

package com.yun.pojo;

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

public class Person {
    private String name;
    @Autowired
    private Dog dog;
    @Autowired
    private Cat cat;

    public Person() {
    }

    // @Nullable表示传入参数时这个属性可以为null
    public Person(@Nullable String name) {
        this.name = name;
    }
}

2.3 @Qualifier

当同一个class在一个xml中配置了多个bean,可以使用 @Qualifier 注解来指定一个具体的bean。

public class Person {
    private String name;
    @Autowired
    @Qualifier(value = "dog2")  // @Qualifier用来指定一个具体的bean
    private Dog dog;
    @Autowired
    private Cat cat;
}
上一篇:023---Rust能力养成系列之第4章 :特性的用法与形式(下)


下一篇:面向对象的特征——多态