弹簧框架中的豆自动布线



我正在尝试从Pro Spring 5 Book中学习Spring。

下面是一个我不明白的自动布线示例:

<?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="fooOne" class="com.apress.prospring5.ch3.xml.Foo"/>
    <bean id="barOne" class="com.apress.prospring5.ch3.xml.Bar"/>
    <bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
        lazy-init="true"/>
    <bean id="targetByType" autowire="byType" class="com.apress.prospring5.ch3.xml.Target"
        lazy-init="true"/>
    <bean id="targetConstructor" autowire="constructor" 
        class="com.apress.prospring5.ch3.xml.Target" lazy-init="true"/>
</beans>

塔里特级

package com.apress.prospring5.ch3.xml;
import org.springframework.context.support.GenericXmlApplicationContext;
public class Target {
    private Foo fooOne;
    private Foo fooTwo;
    private Bar bar;
    public Target() {
    }
    public Target(Foo foo) {
        System.out.println("Target(Foo) called");
    }
    public Target(Foo foo, Bar bar) {
        System.out.println("Target(Foo, Bar) called");
    }
    public void setFooOne(Foo fooOne) {
        this.fooOne = fooOne;
        System.out.println("Property fooOne set");
    }
    public void setFooTwo(Foo foo) {
        this.fooTwo = foo;
        System.out.println("Property fooTwo set");
    }
    public void setBar(Bar bar) {
        this.bar = bar;
        System.out.println("Property bar set");
    }
    public static void main(String... args) {
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
        ctx.load("classpath:spring/app-context-03.xml");
        ctx.refresh();
        Target t = null;
        System.out.println("Using byName:n");
        t = (Target) ctx.getBean("targetByName");
        System.out.println("nUsing byType:n");
        t = (Target) ctx.getBean("targetByType");
        System.out.println("nUsing constructor:n");
        t = (Target) ctx.getBean("targetConstructor");
        ctx.close();
    }
}

福类

package com.apress.prospring5.ch3.xml;
public class Foo {
}

酒吧类

package com.apress.prospring5.ch3.xml;
public class Bar {
}

我不明白的是:

<bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
        lazy-init="true"/>

在知道我们在 bean 定义中没有使用任何属性或构造体注入的情况下,如何注入目标属性(fooOne,fooTwo,bar)?

通常我们应该有这样的东西:

 <property name = "fooOne">
         <bean id = "fooOne" class = "com.apress.prospring5.ch3.xml.Foo"/>
      </property>
<bean id="targetByName" autowire="byName" class="com.apress.prospring5.ch3.xml.Target"
lazy-init="true"/>

因为它将自动连线模式声明为"byName",它具有以下行为(取自文档):

按属性名称自动布线。春天寻找具有相同作用的豆子 名称作为需要自动连线的属性。例如,如果 Bean 定义设置为按名称自动连线,并且它包含一个主节点 属性(也就是说,它有一个 setMaster(..) 方法),Spring 寻找一个 名为 master 的 Bean 定义,并使用它来设置属性。

这意味着它是二传手注射。

回到你的例子,由于Target有以下二传手,spring会做以下操作来注入:

public class Target {
    // Find a bean which name is "fooOne" , and call this setter to inject 
    public void setFooOne(Foo fooOne) {}
    // Find a bean which name is "fooTwo" , and call this setter to inject (As no beans called fooTwo in your example , it will be null) 
    public void setFooTwo(Foo foo) {}
    //Find a bean which name is "bar" , and call this setter to inject (As no beans called bar in your example  , it will be null)   
    public void setBar(Bar bar) {}      
}

当然,如果 bean 的类型与 setter 参数的类型不匹配,就会发生异常。

相关内容

  • 没有找到相关文章

最新更新