您的位置:首页 > 编程语言 > Java开发

第十四章 Spring Bean自动注入(Spring Framework3.1教程)

2014-02-28 19:54 387 查看
你已经知道如何通过XML配置文件声明bean通过<bean>元素配置<constructor-arg>和<property>元素。Spring容器可以自动的包装不用通过<constructor-arg>和<property>元素,这样使你在一个大的Spring应用中不用写很多XML配置文件。

自动包装模式

有如下几种自动装配模式可以应用于指导Spring容器自动装配依赖注入。你使用《bean>元素的“autowire”属性指明bean定义的自动装配类型。

模式

描述

no

这是默认的设置意味着不使用自动包装,你需要使用明确的bean引用实现包装。你不需要做任何特殊的事情对于这种包装。这就是你已经在上面看到的依赖注入。

byName

通过属性名注入。Spring容器通过在XML中查询bean定义的属性名字实现制动包装。它试图匹配包装在配置文件中bean的名字和它属性的名字相同的bean。

byType

自动包装通过属性的数据类型。Spring容器查询bean的属性的类型查询配置文件匹配的类型定义实现自动包装。它试图匹配和装配配置文件中唯一类型相同的bean。这意味着如果这种类型bean存在多个将会引起致命错误。

constructor

和根据类型相似,根据类型匹配构造函数参数。如果不止一个类型的bean符合构造函数的参数,会引发致命的错误。

autodetect

Spring首先常识通过constructor(构造函数)包装,如果不行,然后尝试通过类型包装。

你可以使用byType或者constructor自动包装模式包装数组或者其它集合类型。

自动包装的局限性

自动包装贯穿在整个项目中使用很好。如果一般不使用自动包装,这可能使开发人员迷惑,只包装一两个bean的定义。尽管自动包装可以大大的减少properties或constructor参数,但是你需要思考使用自动包装的限制和缺点。

限制

描述

Overriding possibility

你仍然可以指明依赖使用<constructor-arg>和<property>设置,这会覆盖自动包装。

Primitive data types

你不能自动包装那些称作简单类型的属性如基本类型、字符串和Classes

Confusing nature

自动包装不准确,和明确的包装相比

Spring 自动包装“byName”

这种模式指明根据属性名包装。Spring容器在XML配置文件中查询auto-wire属性设置为byName的bean。然后它试图匹配和装配它的属性,在配置文件中查找bean的定义name相同的bean。如果成功匹配,会注入其他bean,否则会抛出异常。

例如,如果bean定义为autowirebyName在配置文件中,它包含了一个spellChecker属性(换句话说,就是它有一个 setSpellChecker(...)方法),Spring查看一个bean的定义为spellChecker,然后用它去设置这个属性。你仍然可以包装剩余的属性通过<property>标签,如下会举例说明这个概念。

步骤 

描述

1

创建一个SpringExample的项目并在src目录下创建com.tutorialspoint包。

2

在Add External JARs选项卡中添加Spring库如在Spring Hello World章节中所讲。

3

在com.tutorialspoint包下创建TextEditor、SpellChecker 、 MainApp类。

4

在src目录下创建bean的配置文件Beans.xml

5

最后一步在Java类中和Bean配置文件中添加内容,并运行应用。

如下是TextEditor的源代码:

package com.tutorialspoint;

public class TextEditor {
private SpellChecker spellChecker;
private String name;

public void setSpellChecker(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}

public SpellChecker getSpellChecker() {
return spellChecker;
}
public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void spellCheck() {
spellChecker.checkSpelling();
}
}

如下是依赖类SpellChecker的源代码:
package com.tutorialspoint;

public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
}

public void checkSpelling() {
System.out.println("Inside checkSpelling.");
}

}

如下是MainApp的源代码:
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}

如下是通常情况的配置文件Beans.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-3.0.xsd"> 
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker" ref="spellChecker" />
<property name="name" value="Generic Text Editor" />
</bean>

<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>

但是如果你使用自动包装“byName",你的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-3.0.xsd"> 
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor"
autowire="byName">
<property name="name" value="Generic Text Editor" />
</bean>

<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>

一旦你完成了上面源代码和配置文件,运行应用,如果一切正常,会打印如下消息:
Inside SpellChecker constructor.
Inside checkSpelling.

Spring自动装配“byType”

这个指明自动装配根据属性的类型。Spring容器查询bean通过autowire属性设置为byType的bean在XML配置文件中。他们试图装配这些bean通过匹配和装配属性文件中唯一匹配的类型的bean。如果找到匹配类型,会注入成功,否则会抛出异常。

例如,一个bean的定义autowire为byType在配置文件中,它包含一个spellChecker属性是SpellChecker类型。Spring查找bean定义为SpellChecker类型,并使用它去设置这个属性。你仍然可以使用<property>标签包装剩余的属性。接下来的例子会举例说明这个例子。你会发现这个例子和上面的例子没有什么不同除了配置文件的变化。

让我们使用Eclipse IDE按如下的步骤创建一个Spring应用:

步骤 

描述

1

创建一个SpringExample的项目并在src目录下创建com.tutorialspoint包。

2

在Add External JARs选项卡中添加Spring库如在Spring Hello World章节中所讲。

3

在com.tutorialspoint包下创建TextEditor、SpellChecker 、 MainApp类。

4

在src目录下创建bean的配置文件Beans.xml

5

最后一步在Java类中和Bean配置文件中添加内容,并运行应用。

如下是TextEditor的源代码:
package com.tutorialspoint;

public class TextEditor {
private SpellChecker spellChecker;
private String name;

public void setSpellChecker(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}

public SpellChecker getSpellChecker() {
return spellChecker;
}

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

public String getName() {
return name;
}

public void spellCheck() {
spellChecker.checkSpelling();
}
}

如下的源代码是依赖类SpellChecker:

package com.tutorialspoint;

public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
}

public void checkSpelling() {
System.out.println("Inside checkSpelling.");
}

}

如下是MainApp的源代码:
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}

如下是通常的配置文件Beans.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-3.0.xsd"> 
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker" ref="spellChecker" />
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>

但是如果你使用自动包装为“byType”,你的配置文件将会是这样:
Inside SpellChecker constructor.
Inside checkSpelling.

Spring自动装配通过Constructor

这个模式和byType相似,但它适用于构造函数参数,Spring容器查询bean定义为constructor自动包装属性在XML配置文件中。它试图匹配和装配他的构造函数参数,在配置文件中和它类型配置的唯一的bean。如果成功匹配,它将注入,否则会抛出异常。

例如,如果一个bean定义为constructor自动装配在配置文件中,并且它有一个参数类型是SpellChecker类型,Spring查询一个bean定义为SpellChecker类型,并使用它去设置构造函数的参数。你仍然可以使用<constructor-arg>标签去包装剩下的。如下举例说明这个概念。

让我们使用Eclipse IDE按如下的步骤创建一个Spring应用:

步骤 

描述

1

创建一个SpringExample的项目并在src目录下创建com.tutorialspoint包。

2

在Add External JARs选项卡中添加Spring库如在Spring Hello World章节中所讲。

3

在com.tutorialspoint包下创建TextEditor、SpellChecker 、 MainApp类。

4

在src目录下创建bean的配置文件Beans.xml

5

最后一步在Java类中和Bean配置文件中添加内容,并运行应用。

如下是TextEditor的源代码:

package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
private String name;
public TextEditor(SpellChecker spellChecker, String name) {
this.spellChecker = spellChecker;
this.name = name;
}
public SpellChecker getSpellChecker() {
return spellChecker;

}
public String getName() {
return name;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}

如下是依赖类SpellChecker类的源代码:
package com.tutorialspoint;

public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
}

public void checkSpelling() {
System.out.println("Inside checkSpelling.");
}

}

如下是MainApp的源代码:
package com.tutorialspoint;

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

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

TextEditor te = (TextEditor) context.getBean("textEditor");

te.spellCheck();
}
}

如下是普通的配置文件Beans.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-3.0.xsd"> <!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<constructor-arg ref="spellChecker" />
<constructor-arg value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>
但是如果你使用通过“constructor”自动包装,你的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-3.0.xsd"> <!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor"
autowire="constructor">
<constructor-arg value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="SpellChecker" class="com.tutorialspoint.SpellChecker">
</bean>

</beans>

一旦你完成了上面源代码和配置文件,运行应用,如果一切正常,会打印如下消息:

Inside SpellChecker constructor.
Inside checkSpelling.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: