【Spring温故】3. Spring自动装配

一、Spring自动装配介绍:

  当spring装配bean属性时,有时候非常明确就是需要将某个bean注入到其他bean的property中。但spring框架默认是不支持自动装配的,为了应对这种明确的装备场景,Spring提供显示的装配 Bean属性方法(在spring的配置文件的<bean>标签中使用autowire属性来进行声明自动装配)。

  spring目前提供了3类显示自动装配和1类默认装配(手动装配)策略

public interface AutowireCapableBeanFactory{
    //无需自动装配
    int AUTOWIRE_NO = 0;

    //按名称自动装配bean属性
    int AUTOWIRE_BY_NAME = 1;

    //按类型自动装配bean属性
    int AUTOWIRE_BY_TYPE = 2;

    //按构造器自动装配
    int AUTOWIRE_CONSTRUCTOR = 3;

    //过时方法,Spring3.0之后不再支持
    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;
}

二、Spring装配方式具体使用方法:

首先我们先定义三个类(表达某人在某个地方从事某项工作,待遇如何):Person、Address、Work,生成get、set并重写toString()方法:

如:Person类:

package com.monkey.yb.autowire;

public class Person {
    private String name;

    private int age;

    private Address address;

    private Work work;

    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;
    }

    public Work getWork() {
        return work;
    }

    public void setWork(Work work) {
        this.work = work;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", work=" + work +
                '}';
    }
}

Address类:

package com.monkey.yb.autowire;

public class Address {
    private String city;

    private String street;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                ", street='" + street + '\'' +
                '}';
    }
}

Work类:

package com.monkey.yb.autowire;

public class Work {
    private String category;

    private double salary;

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Work{" +
                "category='" + category + '\'' +
                ", salary=" + salary +
                '}';
    }
}

1、默认方式:no

  默认情况下都是使用该模式,使用该模式不会自动装配,需要通过ref来手动指定装配的bean

  例如:在src目录下新建autowire.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="work" class="com.monkey.yb.autowire.Work">
        <property name="category" value="it"></property>
        <property name="salary" value="20000"></property>
    </bean>

    <bean id="address" class="com.monkey.yb.autowire.Address">
        <property name="city" value="杭州"></property>
        <property name="street" value="西湖区"></property>
    </bean>

    <!--未设定autowire参数,表示默认情况下不自动装配,通过ref手动装配-->
    <bean id="person" class="com.monkey.yb.autowire.Person">
        <property name="name" value="tomas"></property>
        <property name="age" value="25"></property>
        <property name="work" ref="work"></property>
        <property name="address" ref="address"></property>
    </bean>

</beans>

在上面配置文件中,person 这个bean中使用ref指定了work和address两个bean,且该bean中配置了对象的属性,再通过main方法进行调用我们可以看出实际效果,如:

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
        Person person = (Person) context.getBean("person");
//        person.getWork();
        System.out.println("未指定装配方式=====" + person);
        System.out.println(person.getWork());
        System.out.println(person.getAddress());
    }

输出结果如下:

未指定装配方式=====Person{name='tomas', age=25, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}

Work{category='it', salary=20000.0}

Address{city='杭州', street='西湖区'}

2、byName:根据名称自动装配,必须将目标bean名称和类中属性名称和bean id设置的完全相同,否则将报错。

  该模式根据bean中property中的name名称自动装配,如果目标bean的中name 与另一个bean中property的name相同,则自动装配这个bean到目标bean的property中(备注:目标bean节点通常需要指定自动装配的类型如:autowire="byName"

<?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="work" class="com.monkey.yb.autowire.Work">
        <property name="category" value="it"></property>
        <property name="salary" value="20000"></property>
    </bean>

    <bean id="address" class="com.monkey.yb.autowire.Address">
        <property name="city" value="杭州"></property>
        <property name="street" value="西湖区"></property>
    </bean>


    <bean id="person1" class="com.monkey.yb.autowire.Person" autowire="byName"></bean>

</beans>

再在main方法中调用:

package com.monkey.yb.autowire;

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

public class Main{
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");

        Person person1 = (Person) context.getBean("person1");
        System.out.println("指定byName装配方式=====" + person1);

    }
}

实际输出结果如下:

指定byName装配方式=====Person{name='null', age=0, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}

3、byType:根据类型装配,若IOC容器中有多个月目标bean类型一致的bean,在这种情况下spring将无法判定哪个bean最合适该属性,所以不能执行自动装配。 

  如果不使用byName来进行装配,还可以使用byType来进行自动装配,它的大体意思就是另一个bean中拥有相同类型的属性自动装配到目标bean的对应属性中。    

<?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="work" class="com.monkey.yb.autowire.Work">
        <property name="category" value="it"></property>
        <property name="salary" value="20000"></property>
    </bean>

    <bean id="address" class="com.monkey.yb.autowire.Address">
        <property name="city" value="杭州"></property>
        <property name="street" value="西湖区"></property>
    </bean>


    <bean id="person2" class="com.monkey.yb.autowire.Person" autowire="byType"></bean>

</beans>

再在main方法中调用:

package com.monkey.yb.autowire;

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

public class Main{
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");

        Person person2 = (Person) context.getBean("person2");
        System.out.println("指定byType装配方式=====" + person2);

    }
}

实际输出结果如下:

指定byType装配方式=====Person{name='null', age=0, address='Address{city='杭州', street='西湖区'}', work=Work{category='it', salary=20000.0}}

上面的例子中,如果使用byType,则work和address中的bean id 都可以省略掉。

3、construtor:通过构造器自动装配,当bean中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用,此处我们就不做详细介绍了。

发布了168 篇原创文章 · 获赞 0 · 访问量 7820

猜你喜欢

转载自blog.csdn.net/weixin_42661815/article/details/102389115
今日推荐