Beans的自动连接(不知道怎么翻译好)
我们知道如何声明以及使用元素并且在xml配置中使用和元素注入
Spring 容器可以在不适用和元素的情况下,使用bean之间的协作关系自动连接,这样有助于减少XML配置文件的内容。
Autowiring Modes
自动装配模式
以下的自动装配模式让Spring容器再依赖注入中使用自动装配。需要在的元素定义中指明自动装配的模式。
No | Mode | Description |
---|---|---|
1 | no | 这种是默认设置,表示没有自动装配,应该使用特殊的bean引用来装配。对于默认设置不需要做额外的事情。 |
2 | byName | 通过属性名称自动装配。Spring容器会在XML配置文件中查找对应属性名的bean来进行自动装配的。 |
3 | byType | 通过属性的数据类型自动装配。Spring容器会在XML中查找对应类型的bean来进行自动装配的。 |
4 | constructor | 和byType类似,但是这个type是构造参数中的type。如果不存在确切沟槽参数类型的bean,那么会导致fatal error。 |
5 | autodetect | Spring首先会尝试通过构造的方式自动装配,如果没有生效,那么会尝试通过type自动装配 |
你可以使用byType或者constructor自动装配模式去装配数组和其他类型的集合。
Limitations with autowiring
自动装配的局限性在项目中大量使用就会很好理解,如果自动装配一般都没有被使用,开发者会对项目当中一个两个自动装配定义感到很困惑。虽然自动装配能够很有效的降低指定属性和构造参数的需求,但是你需要考虑到自动装配的局限性和缺点。
No | Limitations | Description |
---|---|---|
1 | Overriding possibility | 你可以使用和设置指明依赖,但是这将会导致覆盖自动装配 |
2 | Primitive(原始) data types | 你不能自动装配所谓的简单属性,例如基元、字符串以及类 |
3 | Confusing nature | 自动装配不如明确装配,所以如果可能的话尽量明确装配 |
Spring Autowiring ‘byName’
此模式通过name属性进行装配的,Spring容器会在XML配置文件通过byName的方式查找bean,并自动装配。然后,它尝试将它的属性和配置文件中相同名称的beans进行匹配并装配,如果没有找到,则抛异常,如果找到则注入这些beans。
如果一个bean定义在配置文件中被设置成通过名称装配,并且它包含i 个spellChecker属性(当然它有一个setSpellChecker方法),Spring会查找一个名称为spellChecker的bean,并且使用它设置这个属性。你仍然可以使用<property>
设置其他属性,下面的例子将演示这个情况:
Example
SpellChecker.java
package com.soygrow.AutoWiringByName;
public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
TextEditor.java
package com.soygrow.AutoWiringByName;
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();
}
}
MainApp.java
package com.soygrow.AutoWiringByName;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("ByNameBeans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
ByNameBeans.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 = "textEditor" class = "com.soygrow.AutoWiringByName.TextEditor">
<property name = "spellChecker" ref = "spellChecker" />
<property name = "name" value = "Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id = "spellChecker" class = "com.soygrow.AutoWiringByName.SpellChecker"></bean>
</beans>
以上是正常情况下的XML配置文件,如果你是用autowiring 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 = "textEditor" class = "com.soygrow.AutoWiringByName.TextEditor" autowire="byName">
<property name = "name" value = "Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id = "spellChecker" class = "com.soygrow.AutoWiringByName.SpellChecker"></bean>
</beans>
如果一切正常,那么运行结果如下:
Inside SpellChecker constructor.
Inside checkSpelling.
Spring Autowiring ‘byType’
这种模式通过类型来完成自动装配。Spring容器会在XML配置文件中查找装配属性被设置成了byType的beans,如果它的type和配置文件中bean名称完成匹配,则尝试匹配连接属性,如果没有会抛出异常。
例如,如果一个bean定义在XML配置文件中被设置成了autowire byType,并且它包含一个spellChecker类型的spellChecker属性,Spring会查找一个名称为spellChecker的bean定义,并且使用它设置属性。你仍然可以使用<property>
标签装配,下面通过例子来说明该问题:
Example
SpellChecker.java
package com.soygrow.AutoWiringByType;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
TextEditor.java
package com.soygrow.AutoWiringByType;
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();
}
}
MainApp.java
package com.soygrow.AutoWiringByType;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("ByTypeBeans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
ByTypeBeans.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="textEditor" class="com.soygrow.AutoWiringByType.TextEditor">
<property name="spellChecker" ref="spellChecker"/>
<property name="name" value="Generic Text Editor"/>
</bean>
<bean id="spellChecker" class="com.soygrow.AutoWiringByType.SpellChecker"></bean>
</beans>
上面是正常的XML配置文件,如果你使用‘byType’,你的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="textEditor" class="com.soygrow.AutoWiringByType.TextEditor" autowire="byType">
<property name="name" value="Generic Text Editor"/>
</bean>
<bean id="spellChecker" class="com.soygrow.AutoWiringByType.SpellChecker"></bean>
</beans>
如果一切正常,运行结果如下:
Inside SpellChecker constructor.
Inside checkSpelling.
Spring Autowiring by Constructor
这种模式非常类似于byType,但是它适用于构造参数。当autowire属性在XML配置中被设置的情况下,Spring容器会自动查找对应的beans。Spring容器会使用配置文件中确切名称的bean尝试匹配和装配它的构造参数。如果找到匹配的,则注入对应的beans,否则会抛出异常。
如果一个bean的定义在XML被设置了通过构造的自动装配,并且它又一个SpellChecker类型的构造参数,Spring容器会查找一个名称叫做SpellChecker的bean,并且使用它设置构造参数。你仍然可以使用<constructor-arg>
装配其他参数,下面的例子将说明该问题。
Example
SpellChecker.java
package com.soygrow.AutoWiringConstructor;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
TextEditor.java
package com.soygrow.AutoWiringConstructor;
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();
}
}
MainApp.java
package com.soygrow.AutoWiringConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("AutoWireConstructorBeans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
AutoWireConstructorBeans.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">
<!-- Definition for textEditor bean -->
<bean id = "textEditor" class = "com.soygrow.AutoWiringConstructor.TextEditor">
<constructor-arg ref = "spellChecker" />
<constructor-arg value = "Generic Text Editor"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id = "spellChecker" class = "com.soygrow.AutoWiringConstructor.SpellChecker"></bean>
</beans>
上面是正常的XML配置文件,如果使用autowire,你的配置文件如下所示:
<?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">
<!-- Definition for textEditor bean -->
<bean id = "textEditor" class = "com.soygrow.AutoWiringConstructor.TextEditor" autowire="constructor">
<constructor-arg value = "Generic Text Editor"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id = "spellChecker" class = "com.soygrow.AutoWiringConstructor.SpellChecker"></bean>
</beans>
如果一切正常,运行结果如下:
Inside SpellChecker constructor.
Inside checkSpelling.
分析
- byName、byType和constructor三种种方式都可以简化XML配置文件
- 设置autowire,可以实现自动装配,根据名称、类型或者构造的方式
- 作为初学者,只要能看懂这种方式就好,为了便于理解,建议还是不要使用自动装配的方式,只是个人建议