spring——(4)自动装配

前面我们讲Di依赖注入的时候介绍了在xml文件中配置参数注入,Spring 容器可以自动装配相互协作的 bean 之间的关系,这有助于减少编写一个大的基于 Spring 的应用程序的 XML 配置的数量。
下列自动装配模式,它们可用于指示 Spring 容器为来使用自动装配进行依赖注入。你可以使用 元素的 autowire 属性为一个 bean 定义指定自动装配模式。

Tables Are
no 这是默认的设置,它意味着没有自动装配,你应该使用显式的bean引用来连线。你不用为了连线做特殊的事。
byName 由属性名自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byName。然后尝试匹配,并且将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
byType 由属性数据类型自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byType。然后如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。
constructor 类似于 byType,但该类型适用于构造函数参数类型。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生。
autodetect Spring首先尝试通过 constructor 使用自动装配来连接,如果它不执行,Spring 尝试通过 byType 来自动装配。

byName

这种模式由属性名称指定自动装配。在 XML 配置文件中 bean 的 auto-wire 属性设置为 byName。然后,它尝试将它的属性与配置文件中定义为相同名称的 bean 进行匹配和连接。如果找到匹配项,它将注入这些 bean,否则,它将抛出异常。
例:
首先创建一个类AutoWiringDAO:

public class AutoWiringDAO {

    public void say(String word) {
        System.out.println("AutoWiringDAO : " + word);
    }

}

然后在创建一个类AutoWiringService持有AutoWiringDAO的实例,并设置set方法:

public class AutoWiringService {
    //参数名必须和配置文件中的id一致
    private AutoWiringDAO autoWiringDAO;

    public void setAutoWiringDAO(AutoWiringDAO autoWiringDAO) {
        this.autoWiringDAO = autoWiringDAO;
    }

    public void say(String word) {
        this.autoWiringDAO.say(word);
    }

}

按照之前的操作,我们要这样修改配置文件:


<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="autoWiringService" class="com.mss.test.AutoWiringService">
        <property name="autoWiringDAO" ref="autoWiringDAO" />
    bean>

     //id必须和类文件中的参数名一样
    <bean id="autoWiringDAO" class="com.mss.test.AutoWiringDAO">bean>

beans>

如果使用byName要怎样操作呢:

<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="autoWiringService" class="com.mss.test.AutoWiringService" autowire="byName">bean>

    <bean id="autoWiringDAO" class="com.mss.test.AutoWiringDAO">bean>

beans>

我们测试一下:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase{

    public TestOneInterface() {
        super("classpath*:spring-ioc.xml");
    }

    @Test
    public void testAutoWriter() {
        AutoWiringService autoWiringService=super.getBean("autoWiringService");
        autoWiringService.say("hello");
    }
}

输出结果:

AutoWiringDAO : hello

byType

我们知道byName是类中的参数和配置文件中id定义为相同名称的 bean 进行匹配和连接,他的限制就是参数名必须和bean中的id一致,而byType不需要,就算bean没有指定id,他依然可以运行。
我们修改一下之前的配置文件:


<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="autoWiringService" class="com.mss.test.AutoWiringService" autowire="byType">bean>

    <bean class="com.mss.test.AutoWiringDAO">bean>

beans>

可以看到我们把autowire的类型修改成了byType,并且把AutoWiringDAO的id删掉,现在运行一下测试类:

AutoWiringDAO : hello

运行结果和原来一样。

constructor

这种模式与 byType 非常相似,但它应用于构造器参数。在 XML 配置文件中 bean的 autowire 属性设置为 constructor。然后,它尝试把它的构造函数的参数与配置文件中 bean 名称中的一个进行匹配和连线。如果找到匹配项,它会注入这些 bean,否则,它会抛出异常。
首先在AutoWiringService 中添加构造函数:

public class AutoWiringService {

    private AutoWiringDAO autoWiringDAO;

    public AutoWiringService(AutoWiringDAO autoWiringDAO) {
        this.autoWiringDAO = autoWiringDAO;
    }

    public void setAutoWiringDAO(AutoWiringDAO autoWiringDAO) {
        this.autoWiringDAO = autoWiringDAO;
    }

    public void say(String word) {
        this.autoWiringDAO.say(word);
    }

}

如果是手动注入,应该这样修改配置文件:


<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="autoWiringService" class="com.mss.test.AutoWiringService">
        <constructor-arg name="autoWiringDAO" ref="autoWiringDAO">constructor-arg>
    bean>

    <bean id="autoWiringDAO" class="com.mss.test.AutoWiringDAO">bean>

beans>

现在我们使用自动注入配置:


<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="autoWiringService" class="com.mss.test.AutoWiringService" autowire="constructor">bean>

    <bean class="com.mss.test.AutoWiringDAO">bean>

beans>

可以看到我没有指定id,也就是说他也是根据类型装配。运行结果如下:

AutoWiringDAO : hello

上面我们指定装配方式都是在bean结点下指定的,这样只在当前bean中有效,可不可以配置全局有效呢?当然是可以的了,我们只需要在beans结点中配置default-autowire属性即可。但是他的优先级是没有autowire高的,也就说如果我在bean结点下配置了autowire属性,即使在beans结点中配置default-autowire属性也不会生效。


<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"
        default-autowire="byName">

beans>

你可能感兴趣的:(Spring)