简体   繁体   English

豆在春季框架中自动装配

[英]bean autowiring in spring framwork

I'm trying to learn Spring from the Pro Spring 5 Book. 我正在尝试从Pro Spring 5 Book中学习Spring。

Here is an example i didn't understood on autowiring: 这是我在自动装配中不了解的示例:

<?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>

Tarjet Class Tarjet级

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();

    }
}

Foo Class 富班

package com.apress.prospring5.ch3.xml;

public class Foo {

}

Bar Class 酒吧班

package com.apress.prospring5.ch3.xml;

public class Bar {

}

What i didn't understood: 我不明白的是:

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

How the Target attriubutes (fooOne,fooTwo,bar) will be injected knowing we have not used any property or constructer injection in the bean defintion? 知道我们在bean定义中没有使用任何属性或构造方法注入时,如何注入目标属性(fooOne,fooTwo,bar)?

normally we should have something like : 通常我们应该有这样的东西:

 <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"/>

Because it declares the auto-wired mode as " byName " which has following behaviour (taken from docs ) : 因为它将自动连线模式声明为“ byName ”,所以具有以下行为(取自docs ):

Autowiring by property name. 按属性名称自动布线。 Spring looks for a bean with the same name as the property that needs to be autowired. Spring寻找与需要自动装配的属性同名的bean。 For example, if a bean definition is set to autowire by name and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master and uses it to set the property. 例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(..)方法),那么Spring将查找一个名为master的bean定义,并使用它来设置该属性。

That means it is setter injection. 这意味着它是二传手注射。

Back to your example , since Target has the following setters , spring will do the following to inject : 回到您的示例,由于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) {}      
}

Of course , if the bean 's type does not match the type of the setter argument, exception will happens. 当然,如果bean的类型与setter参数的类型不匹配,则会发生异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM