目录
(5)为Properties注入值(key和Value是字符串类型类型)
1.注入分类
(1)设值注入(多用)
设值注入是指,通过setter方法传入被调用者的实例。这种注入方式简单、直观,因而在Spring的依赖注入中大量使用。
当指定bean的某属性值为另一bean的实例时,通过ref指定它们间的引用关系。ref的值必须为某bean的id值。
<!-- 注册School -->
<bean id="mySchool" class="com.lmm.di01.School">
<property name="name" value="清华大学"/>
<property name="score" value="695"/>
</bean>
<!-- 注册Student -->
<bean id="myStudent" class="com.lmm.di01.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school" ref="mySchool"/>
</bean>
对于其它Bean对象的引用,除了<bean/>标签的ref属性外,还可以使用<ref/>标签。
(2)构造注入
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。
<constructor-arg />标签中用于指定参数的属性有:
- name:指定参数名称。
- index:指明该参数对应着构造器的第几个参数,从0开始。不过,该属性不要也行,但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致。
另外,type属性可用于指定其类型。基本类型直接写类型关键字即可,非基本类型需要写全限定性类名。
<?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">
<!-- 注册School -->
<bean id="mySchool" class="com.bjpowernode.di02.School">
<property name="name" value="清华大学"/>
</bean>
<!-- 注册Student -->
<bean id="myStudent" class="com.lmm.di02.Student">
<constructor-arg name="name" value="李四"/>
<constructor-arg name="age" value="24"/>
<constructor-arg name="school" ref="mySchool"/>
<!--
<constructor-arg index="0" value="李四"/>
<constructor-arg index="1" value="24"/>
<constructor-arg index="2" ref="mySchool"/>
-->
<!--
<constructor-arg value="李四"/>
<constructor-arg value="24"/>
<constructor-arg ref="mySchool"/>
-->
</bean>
</beans>
2.命名空间注入(了解)
对于设值注入与构造注入,在配置文件中,除了使用<property/>或<constructor-arg/>标签外,还可使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分为p命名空间注入与c命名空间注入。
p命名空间注入:采用设值注入方式,故需要有相应的setter
c命名空间注入:采用构造注入方式,故需要有相应的构造器
这里就不详细说了~
3.集合属性的注入(重点)
package com.lmm.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 String[] myStrs;
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 setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
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) + ", myStrs="
+ Arrays.toString(myStrs) + ", myList=" + myList + ", mySet="
+ mySet + ", myMap=" + myMap + ", myPros=" + myPros + "]";
}
}
(1)为数组注入值
<property name="schools">
<array>
<ref bean="mySchool"/>
<ref bean="mySchool2"/>
</array>
</property>
(2)为List注入值
<property name="myList">
<list>
<value>合肥</value>
<value>济南</value>
</list>
</property>
(3)为Set注入值
<property name="mySet">
<set>
<value>安徽</value>
<value>合肥</value>
</set>
</property>
(4)为Map注入值(key和Value是任意类型)
<property name="myMap">
<map>
<entry key="mobile" value="1234567"/>
<entry key="QQ" value="7654321"/>
</map>
</property>
(5)为Properties注入值(key和Value是字符串类型类型)
<property name="myPros">
<props>
<prop key="education">大学</prop>
<prop key="gender">男</prop>
</props>
</property>
以上内容的简洁写法:
<?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">
<!-- 注册School -->
<bean id="mySchool" class="com.lmm.di06.School">
<property name="name" value="清华大学"/>
</bean>
<bean id="mySchool2" class="com.lmm.di06.School">
<property name="name" value="北京大学"/>
</bean>
<!-- 注册Student -->
<bean id="mySome" class="com.lmm.di06.Some">
<property name="schools" ref="mySchool"/>
<property name="myStrs" value="中国,北京"/>
<property name="myList" value="合肥,济南"/>
<property name="mySet" value="安徽,合肥"/>
<property name="myMap">
<map>
<entry key="mobile" value="1234567"/>
<entry key="QQ" value="7654321"/>
</map>
</property>
<property name="myPros">
<props>
<prop key="education">大学</prop>
<prop key="gender">男</prop>
</props>
</property>
</bean>
</beans>
4.对于域属性的自动注入
所谓的域属性就是对象属性,如上面的School属性。那么他该如何自动注入呢?
(1)byName方式自动注入
<!-- 注册School -->
<bean id="school" class="com.bjpowernode.di07.School">
<property name="name" value="清华大学"/>
</bean>
<!-- 注册Student
autowire="byName" 会从容器中查找与实体类的域属性同名的Bean的id,并将该Bean对象自动注入给该域属性
-->
<bean id="myStudent" class="com.bjpowernode.di07.Student" autowire="byName">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
autowire="byName" 会从容器中查找与实体类的域属性同名的Bean的id,并将该Bean对象自动注入给该域属性。就是如下类中的域属性(画红线的地方),他会自动找到id=school的属性,自动注入。
(2)byType方式自动注入
使用byType方式自动注入,要求:配置文件中被调用者bean的class属性指定的类,要与代码中调用者Bean类的某域属性类型同源。即要么相同,要么有is-a关系(子类,或是实现类)。但这样的同源的被调用bean只能有一个,即使是多一个子类也不行。多于一个,容器就不知该匹配哪一个了。
<?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">
<!-- 注册School -->
<bean id="mySchool" class="com.lmm.di08.School">
<property name="name" value="清华大学"/>
</bean>
<!--
<bean id="myPrimarySchool" class="com.bjpowernode.di08.PrimarySchool">
<property name="address" value="海淀区"/>
</bean>
-->
<!-- 注册Student
autowire="byType" 会从容器中查找与实体类的域属性类型 具有is-a关系 的Bean,并将该Bean对象自动注入给该域属性
-->
<bean id="myStudent" class="com.lmm.di08.Student" autowire="byType">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
</beans>
5.使用SPEL注入
SPEL,Spring Expression Language,即Spring EL表达式语言。即,在Spring配置文件中为Bean的属性注入值时,可直接使用SPEL表达式计算的结果。SPEL表达式以#开头,后跟一对大括号。用法: <bean id=“abc” value=“#{…}”/>
<?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">
<!-- 注册School -->
<bean id="myPerson" class="com.lmm.di09.Person">
<property name="pname" value="李四" />
<property name="page" value="#{T(java.lang.Math).random() * 50}" />
</bean>
<bean id="myStudent" class="com.lmm.di09.Student">
<property name="name" value="#{myPerson.pname}" />
<!-- <property name="age" value="#{myPerson.page > 25 ? 25 : myPerson.page}"/> -->
<property name="age" value="#{myPerson.computeAge() }" />
</bean>
</beans>
其它用法:
(1) <property name=“school” value=“#{mySchool}”/>
引用另一个bean。指定school的值为另一个Bean实例mySchool。
(2) <property name=“schoolName” value=“#{mySchool.name.toUpperCase()}”/>
使用指定属性,并使用其方法。指定schoolName的值为mySchool的name属性值,并将其字母均转换为大写字母(toUpperCase()方法)。
6.使用内部Bean注入(了解)
若不希望代码直接访问某个bean,即,在代码中通过getBean方法获取该Bean实例, 则可将该Bean的定义放入调用者bean定义的内部。
<!-- 注册Student 将school的值放到myStudent内部,其他访问不到这个bean-->
<bean id="myStudent" class="com.lmm.di10.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school">
<bean class="com.lmm.di10.School">
<property name="name" value="清华大学"/>
</bean>
</property>
</bean>
7.使用同类抽象Bean注入(了解)
当若干Bean实例同属于一个类,且这些实例的属性值又有相同值时,可以使用抽象Bean,以简化配置文件。
抽象Bean是用于让其它bean继承的。这个bean在Bean类中是不能通过getBean方法获取的。设置abstract属性为true来指明该bean为抽象bean, 默认值为false。 不过,该bean不为抽象bean时,也可被继承。 只不过,在应用中,用于被继承的bean一般为抽象bean。
简化所有的其他代码
<property name="school" value="清华大学"/>
<property name="department" value="计算机系"/>
令abstract="true",使得baseStudent抽象Bean不能被直接创建!
<?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 -->
<bean id="baseStudent" class="com.lmm.di11.Student" abstract="true">
<property name="school" value="清华大学"/>
<property name="department" value="计算机系"/>
</bean>
<bean id="myStudent" parent="baseStudent">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
<bean id="myStudent2" parent="baseStudent">
<property name="name" value="李四"/>
<property name="age" value="24"/>
</bean>
<bean id="myStudent3" parent="baseStudent">
<property name="name" value="王五"/>
<property name="age" value="25"/>
</bean>
</beans>
8.使用异类抽象Bean注入(了解)
当若干不同的类对象具有相同的属性,且其值也相同时,可使用异类抽象Bean。
此时baseBean不能被创建,所以parent="baseBean"
<?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 -->
<bean id="baseBean" abstract="true">
<property name="school" value="清华大学"/>
<property name="department" value="计算机系"/>
</bean>
<bean id="myStudent" class="com.lmm.di12.Student" parent="baseBean">
<property name="name" value="张三"/>
<property name="age" value="23"/>
</bean>
<bean id="myTeacher" class="com.lmm.di12.Teacher" parent="baseBean">
<property name="name" value="Reyco"/>
<property name="workAge" value="18"/>
</bean>
</beans>
9.为应用指定多个Spring配置文件(重点)
在实际应用里,随着应用规模的增加,系统中Bean数量也大量增加,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将Spring配置文件分解成多个配置文件。
(1)平等关系的配置文件(用的多)
各配置文件间为并列关系,不分主次。
调用方法:
package com.lmm.di13;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01() {
// 创建容器对象,加载Spring配置文件
/*
* String resource = "com/bjpowernode/di13/spring-base.xml"; String
* resource2 = "com/bjpowernode/di13/spring-beans.xml";
* ApplicationContext ac = new ClassPathXmlApplicationContext(resource,
* resource2);
*/
/*
* String resource = "com/bjpowernode/di13/spring-base.xml"; String
* resource2 = "com/bjpowernode/di13/spring-beans.xml"; String[]
* resources = {resource, resource2}; ApplicationContext ac = new
* ClassPathXmlApplicationContext(resources);
*/
String resource = "com/lmm/di13/spring-*.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
Student student = (Student) ac.getBean("myStudent");
System.out.println(student);
Teacher teacher = (Teacher) ac.getBean("myTeacher");
System.out.println(teacher);
}
}
(2)包含关系的配置文件
各配置文件中有一个总文件,总配置文件将各其它子文件通过<import/>引入。在Java代码中只需要使用总配置文件对容器进行初始化即可。
<?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">
<!--
<import resource="classpath:com/bjpowernode/di14/spring-base.xml"/>
<import resource="classpath:com/bjpowernode/di14/spring-beans.xml"/>
-->
<import resource="classpath:com/lmm/di14/spring-*.xml"/>
</beans>
package com.lmm.di14;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01() {
// 创建容器对象,加载Spring配置文件(直接加载总的就可以)
String resource = "com/lmm/di14/springTotal.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
Student student = (Student) ac.getBean("myStudent");
System.out.println(student);
Teacher teacher = (Teacher) ac.getBean("myTeacher");
System.out.println(teacher);
}
}
注意:总配置文件不能和总配置文件相同,否则通配符会通配到自己,出现错误