在上一篇博客中主要是bean的装配,这一篇看bean的注入。
Bean实例在调用无参构造器之后就开始初始化其属性。初始化是由容器进行完成的,也被称之为注入。注入有两种类型:设值注入和构造注入。
一、设值注入
设值注入是指通过setter方法传入bean的实例。这种方式简单而且直观。
1、定义bean
package com.fdd.di01;
public class Student {
private String name;
private int age;
//get和set
//toString方法
}
2、看配置文件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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册Service
-->
<bean id="myStudent" class="com.fdd.di01.Student">
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
</bean>
</beans>
我们可以看到其属性值是直接配置在文件中的。
3、接下来看一看测试:
public class MyTest {
@Test
public void test01(){
String resource = "com/fdd/di01/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
Student student =(Student) ac.getBean("myStudent");
System.out.println(student);
}
}
4、看一下输出结果吧。
注意:当一个bean中含有另外一个bean的实例的时候,只需要使用ref指定他们的引用关系。
1、修改student类
package com.fdd.di01;
public class Student {
private String name;
private int age;
private School school;
//同上
}
2、修改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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mySchool" class="com.fdd.di01.School">
<property name="name" value="清华大学"></property>
</bean>
<bean id="myStudent" class="com.fdd.di01.Student">
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
<property name="school" ref="mySchool"></property>
</bean>
</beans>
我们也可以使用另外一种写法。都是一样的。
再来看一下输出结果:
二、构造注入
构造注入是指在调用bean的同时,完成被调用者的实例化。也就是使用构造器设置依赖关系。
1、首先是bean的修改
2、修改applicationContext
<?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="mySchool" class="com.fdd.di01.School">
<property name="name" value="北京大学"></property>
</bean>
<bean id="myStudent" class="com.fdd.di01.Student">
<constructor-arg name="name" value="李四"/>
<constructor-arg name="age" value="23"/>
<constructor-arg name="school" ref="mySchool"/>
</bean>
</beans>
我们可以看到<constructor-arg>有以下几个属性:
- name:指定的参数名称。
- index:指定该参数对应构造器的第几个参数,从0开始。(可选)
- type:指定其类型,基本类型直接写类型关键字,比如String\、int等等,自定义类型,要写全限定性类名。
- ref:指向其他的bean
- value:值
3、测试类不变
4、查看结果
三、集合属性注入
上面只是对基本数据类型,或者是其他bean的注入,如果注入的数据类型为集合类型怎么办呢?
1、bean定义
public class MyCollections {
private String[] strs;
private List<Student> students;
private Set<String> mySet;
private Map<String,Integer> myMap;
private Properties myPro;
//必须添加,否则会报不能找到构造方法的错误。原因不详
public MyCollections() {
super();
}
public MyCollections(String[] strs, List<Student> students,
Set<String> mySet, Map<String, Integer> myMap, Properties myPro) {
super();
this.strs = strs;
this.students = students;
this.mySet = mySet;
this.myMap = myMap;
this.myPro = myPro;
}
//get和set方法
//toString方法
}
2、applicationContext配置文件
<?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="mySchool" class="com.fdd.di05.School">
<property name="name" value="北京大学"></property>
</bean>
<bean id="myStudent1" class="com.fdd.di05.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school" ref="mySchool"/>
</bean>
<bean id="myStudent2" class="com.fdd.di05.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<property name="school" ref="mySchool"/>
</bean>
<bean id="myCollections" class="com.fdd.di05.MyCollections">
<property name="strs">
<array>
<value>abc</value>
<value>abc</value>
</array>
</property>
<property name="students">
<list>
<ref bean="myStudent1"/>
<ref bean="myStudent2"/>
</list>
</property>
<property name="mySet">
<set>
<value>高中</value>
<value>初中</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="height" value="100"/>
<entry key="weight" value="80"/>
</map>
</property>
<property name="myPro">
<props>
<prop key="tel">124322354</prop>
<prop key="address">西安</prop>
</props>
</property>
</bean>
</beans>
3、测试文件
public class MyTest {
@Test
public void test01(){
String resource = "com/fdd/di05/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
MyCollections student =(MyCollections) ac.getBean("myCollections");
System.out.println(student);
}
}
4、测试结果
四、域属性的注入
1、byName自动注入
当配置文件中被调用者Bean的id与代码中调用者bean类的属性名相同时候,可以使用byName方式。容器会比较这两种方式自动注入。
2、byType自动注入
我们看到这两种方式只有一点差别。有什么差别呢?byName比较容易理解。byType可以这样理解。student的school属性,与配置文件中的school是同一个
但是这种方式必须说明,student中的school只有一个。
3、使用SPEL注入
4、使用内部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 id="myStudent" class="com.fdd.di01.Student" >
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
<property name="school">
<bean class="com.fdd.di01.School">
<property name="name" value="西北工业大学"/>
</bean>
</property>
</bean>
</beans>
5、使用同类抽象bean注入
意思是当student有两个,这两个是同一个学校。那么我们先定义一个抽象类。然后使得这两个学生集成这个抽象类即可
6、使用异类抽象bean注入
比如说现在有一个学生类一个教师类,这两个类之间有很多相通的属性。
那么我们就可以定义一个抽象类,使得这两个类继承自这个抽象类