Spring学习笔记
Bean Definition Inheritance
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>
<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
Dependency Injection
Constructor-based Dependency Injection
public TextEditor(SpellChecker spellChecker) {
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
...
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<constructor-arg ref="spellChecker"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
Setter-based Dependency Injection
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
...
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker" ref="spellChecker"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
Injecting Inner Beans
<!-- Definition for textEditor bean using inner bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker">
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker"/>
</property>
</bean>
Injecting Collection
元素 | 描述 |
---|---|
<list> | This helps in wiring ie injecting a list of values, allowing duplicates. |
<set> | This helps in wiring a set of values but without any duplicates. |
<map> | This can be used to inject a collection of name-value pairs where name and value can be of any type. |
<props> | This can be used to inject a collection of name-value pairs where the name and value are both Strings. |
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.tutorialspoint.JavaCollection">
<!-- results in a setAddressList(java.util.List) call -->
<property name="addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<!-- results in a setAddressSet(java.util.Set) call -->
<property name="addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
<!-- results in a setAddressMap(java.util.Map) call -->
<property name="addressMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="USA"/>
</map>
</property>
<!-- results in a setAddressProp(java.util.Properties) call -->
<property name="addressProp">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
</bean>
Injecting Bean References
<!-- Bean Definition to handle references and values -->
<bean id="..." class="...">
<!-- Passing bean reference for java.util.List -->
<property name="addressList">
<list>
<ref bean="address1"/>
<ref bean="address2"/>
<value>Pakistan</value>
</list>
</property>
<!-- Passing bean reference for java.util.Set -->
<property name="addressSet">
<set>
<ref bean="address1"/>
<ref bean="address2"/>
<value>Pakistan</value>
</set>
</property>
<!-- Passing bean reference for java.util.Map -->
<property name="addressMap">
<map>
<entry key="one" value="INDIA"/>
<entry key ="two" value-ref="address1"/>
<entry key ="three" value-ref="address2"/>
</map>
</property>
</bean>
Injecting null and empty string values
Injecting null:
<bean id="..." class="exampleBean">
<property name="email"><null/></property>
</bean>
Injecting empty string values:
<bean id="..." class="exampleBean">
<property name="email" value=""/>
</bean>
Beans Auto-Wiring
no
This is default setting which means no autowiring and you should use explicit bean reference for wiring. You have nothing to do special for this wiring. This is what you already have seen in Dependency Injection chapter.
byName
Normal condition:
<!-- 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>
Use autowiring ‘byName’:
<!-- 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>
byType
Normal condition:
<!-- 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>
Use autowiring ‘byType’:
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor"
autowire="byType">
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean class="com.tutorialspoint.SpellChecker">
</bean>
by constructor
Normal condition:
<!-- 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>
Use autowiring ‘by constructor’:
<!-- 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 class="com.tutorialspoint.SpellChecker">
</bean>
autodetect
Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType.
autowiring的使用限制
限制 | 描述 |
---|---|
可能被覆盖 | 在使用autowiring的同时又使用了<constructor-arg> 和 <property> |
原始数据类型 | autowiring不能使用在原始数据类型上,如String等 |
容易混淆 | autowiring没有显示wiring那么明确,应尽量使用显示wiring |
Annotation Based Configuration
@Required
@Required
应用于bean
属性的setter
方法。它表明受影响的bean
属性必须包含在XML
配置文件中,否则会抛出BeanInitializationException
异常。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<!-- Definition for student bean -->
<bean id="student" class="com.tutorialspoint.Student">
<property name="name" value="Zara" />
<property name="age" value="11"/>
</bean>
</beans>
若将属性age
去掉,即<!-- property name="age" value="11"-->
,则会抛出Property 'age' is required for bean 'student'
。
@Autowired
@Autowired
注释对在哪里以及如何完成自动连接提供了更多的精细的控制。
Setter方法中的@Autowired
可以在Setter
方法上使用@Autowired
以替代XML
配置文件中的<property>
元素。当Spring
发现在Setter
方法上使用了@Autowired
,它将在该方法上执行byType
自动连接。
TextEditor.java
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
private SpellChecker spellChecker;
@Autowired
public void setSpellChecker( SpellChecker spellChecker ){
this.spellChecker = spellChecker;
}
public SpellChecker getSpellChecker( ) {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
Beans.xml
<context:annotation-config/>
<!-- Definition for textEditor bean without constructor-arg -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
</bean>
<!-- Definition for spellChecker bean -->
<bean class="com.tutorialspoint.SpellChecker">
</bean>
属性中的@Autowired
可以在属性上使用@Autowired
以替代Setter
方法。
TextEditor.java
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
@Autowired
private SpellChecker spellChecker;
public TextEditor() {
System.out.println("Inside TextEditor constructor." );
}
public SpellChecker getSpellChecker( ){
return spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Beans.xml
<context:annotation-config/>
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
</bean>
<!-- Definition for spellChecker bean -->
<bean class="com.tutorialspoint.SpellChecker">
</bean>
构造器中的@Autowired
可以在构造器上使用@Autowired
以替代<constructor-arg>
元素。
TextEditor.java
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
private SpellChecker spellChecker;
@Autowired
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Beans.xml
<context:annotation-config/>
<!-- Definition for textEditor bean without constructor-arg -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
</bean>
<!-- Definition for spellChecker bean -->
<bean class="com.tutorialspoint.SpellChecker">
</bean>
@Autowired的(required=false)选项
默认情况下,@Autowired
注解意味着依赖是必须的,即它所依赖的属性必须包含在XML
配置文件中。然而,可以通过@Autowired
的(required=false)
选项关闭该行为。同@Required
注解类似。
Student.java
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class Student {
private Integer age;
private String name;
@Autowired(required=false)
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
@Autowired
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
说明:
age
属性不需任何传递参数。
@Qualifier
存在这样一种情形:当创建多个同一类型的bean时,在依赖时又只想依赖其中的某一个时该怎么做呢?
我们可以将@Qualifier
注解和@Autowired
注解一起使用来确定到底依赖哪一个bean。
Profile.java
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Profile {
@Autowired
@Qualifier("student1")
private Student student;
public Profile(){
System.out.println("Inside Profile constructor." );
}
public void printAge() {
System.out.println("Age : " + student.getAge() );
}
public void printName() {
System.out.println("Name : " + student.getName() );
}
}
Beans.xml
<context:annotation-config/>
<!-- Definition for profile bean -->
<bean id="profile" class="com.tutorialspoint.Profile">
</bean>
<!-- Definition for student1 bean -->
<bean id="student1" class="com.tutorialspoint.Student">
<property name="name" value="Zara" />
<property name="age" value="11"/>
</bean>
<!-- Definition for student2 bean -->
<bean id="student2" class="com.tutorialspoint.Student">
<property name="name" value="Nuha" />
<property name="age" value="2"/>
</bean>