注入分类
(1)设值注入:先调用 Bean 的无参构造函数,然后通过 setter 方法传入被调用者的实例。
<!-- bean definitions here --> <bean id="mySchool" class="com.neu.di01.School"> <property name="sname" value="neu"></property> </bean> <bean id="myStudent" class="com.neu.di01.Student"> <property name="name" value="js"></property> <property name="age" value="23"></property> <property name="school" ref="mySchool"></property> </bean>
注:对于其他 Bean 对象的引用,除了<bean/>标签的 ref 属性外,还可以使用 <ref/> 标签
(2)构造注入:在构造调用者实例的同时,完成了被调用者的实例化。即使用构造器设置依赖关系
<constructor-arg> 标签中用于指定参数的属性:
name:指定参数名称
index:指明该参数对应构造器的第几个参数,从0开始,不过该属性可以不需要,但是需要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致
另外,type属性可用于指定类型,基本类型直接写类型关键字即可,非基本类型需要写全限定性类名
<!-- bean definitions here --> <bean id="mySchool" class="com.neu.di02.School"> <property name="sname" value="neu"></property> </bean> <bean id="myStudent" class="com.neu.di02.Student"> <constructor-arg name="name" value="js"></constructor-arg> <constructor-arg name="age" value="22"></constructor-arg> <constructor-arg name="school" ref="mySchool"></constructor-arg> <!-- <constructor-arg value="js"></constructor-arg> <constructor-arg value="22"></constructor-arg> <constructor-arg ref="mySchool"></constructor-arg> --> <!-- <constructor-arg index="0" value="js"></constructor-arg> <constructor-arg index="1" value="22"></constructor-arg> <constructor-arg index="2" ref="mySchool"></constructor-arg> --> </bean>
(3)特定接口注入:采用了侵入式编程,污染了代码,几乎不用
命名空间注入(了解)
对于设值注入和构造注入,除了使用 <property/>或<constructor-arg/>标签外,还可以使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分别以 p 命名空间和 c 命名空间注入。
p 命名空间注入:采用设值注入,需要相应的 setter 方法
c 命名空间注入:采用构造注入,需要相应的构造器
(1)p 命名空间注入
采用约束
xmlns:p="http://www.springframework.org/schema/p"
<!-- bean definitions here --> <bean id="mySchool" class="com.neu.di03.School" p:sname="北京大学"></bean> <bean id="myStudent" class="com.neu.di03.Student" p:name="张三" p:age="22" p:school-ref="mySchool"></bean>
(2)c 命名空间注入
采用约束
xmlns:c="http://www.springframework.org/schema/c"
<!-- bean definitions here --> <bean id="mySchool" class="com.neu.di04.School"> <property name="sname" value="清华大学"></property> </bean> <bean id="myStudent" class="com.neu.di04.Student" c:name="张三" c:age="22" c:school-ref="mySchool"></bean>
集合属性注入
分别为数组,List,Set,Map,Properties注入值,例子如下,
School.java
package com.neu.di05; public class School { private String sname; public void setSname(String sname) { this.sname = sname; } @Override public String toString() { return "School [sname=" + sname + "]"; } }
Some.java
package com.neu.di05; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Some { private School[] schools; private List<String> myList; private Set<String> mySet; private Map<String, Object> myMap; private Properties myPros; public void setSchools(School[] schools) { this.schools = schools; } public void setMyList(List<String> myList) { this.myList = myList; } public void setMySet(Set<String> mySet) { this.mySet = mySet; } public void setMyMap(Map<String, Object> myMap) { this.myMap = myMap; } public void setMyPros(Properties myPros) { this.myPros = myPros; } @Override public String toString() { return "Some [schools=" + Arrays.toString(schools) + ", myList=" + myList + ", mySet=" + mySet + ", myMap=" + myMap + ", myPros=" + myPros + "]"; } }
applicationContext.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" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- bean definitions here --> <bean id="school1" class="com.neu.di05.School"> <property name="sname" value="清华大学"></property> </bean> <bean id="school2" class="com.neu.di05.School"> <property name="sname" value="北京大学"></property> </bean> <bean id="some" class="com.neu.di05.Some"> <property name="schools"> <array> <ref bean="school1" /> <ref bean="school2" /> </array> </property> <property name="myList"> <list> <value>张三</value> <value>李四</value> </list> </property> <property name="mySet"> <set> <value>北京</value> <value>上海</value> </set> </property> <property name="myMap"> <map> <entry key="QQ" value="123"></entry> <entry key="WeiXin" value="456"></entry> </map> </property> <property name="myPros"> <props> <prop key="地址">辽宁省沈阳市</prop> <prop key="名称">neu</prop> </props> </property> </bean> </beans>
applicationContext.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" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- bean definitions here --> <bean id="school1" class="com.neu.di06.School"> <property name="sname" value="清华大学"></property> </bean> <bean id="school2" class="com.neu.di06.School"> <property name="sname" value="北京大学"></property> </bean> <bean id="some" class="com.neu.di06.Some"> <property name="schools"> <array> <ref bean="school1" /> <ref bean="school2" /> </array> </property> <property name="arrays" value="aaa,bbb"></property> <property name="myList" value="张三s,李四"></property> <property name="mySet" value="北京,上海"></property> <property name="myMap"> <map> <entry key="QQ" value="123"></entry> <entry key="WeiXin" value="456"></entry> </map> </property> <property name="myPros"> <props> <prop key="地址">辽宁省沈阳市</prop> <prop key="名称">neu</prop> </props> </property> </bean> </beans>
MyTest.java
package com.neu.di05; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test public void test01() { // 加载Spring配置文件,创建Spring容器对象 String resource = "com/neu/di05/applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(resource); // 从容器中获取指定的Bean对象 Some some = (Some) ac.getBean("some"); System.out.println(some); ((ClassPathXmlApplicationContext) ac).close(); } }
对于域属性的自动注入
byName 方式自动注入
配置文件中被调用者的 Bean 的 id 值与代码中调用者 Bean 的属性名相同时,可以使用 byName 的方式,让容器自动将被调用者 Bean 注入给调用者 Bean 。
如图中 id 为 school 的 Bean,正好对应 Student 类中定义的 school 成员变量,在 id 为 myStudent 的 Bean 中直接定义自动注入方式 autowrite=“byName” 即可
byType 方式自动注入
配置文件中被调用者Bean的class属性指定的类,必须要与代码中被调用者Bean类的某域属性同源,即,相同或者具有is-a关系(子类,或者实现类)。同源的被调用者Bean只能有一个,多于一个则会报错,不知道该匹配哪一个。