文章目录
哪三种方式?
- 使用构造器注入
- 使用setter注入
- 使用自动装配
准备工作
- 配置文件
spring-di.xml
- 包:
biuaxia.bean
- 包:
biuaxia.test
- bean包下有Man类
package biuaxia.bean;
/**
* Class Describe:
*
* @author biuaxia
* @date 2018/11/13
* @time 17:55
*/
public class Man {
private Person person;
@Override
public String toString() {
return "Man{" +
"person=" + person +
'}';
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Man() {
}
public Man(Person person) {
this.person = person;
}
}
- bean包下有Person类
package biuaxia.bean;
/**
* Class Describe:
*
* @author biuaxia
* @date 2018/11/13
* @time 17:39
*/
public class Person {
String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
使用构造器注入
容器调用带有一组参数的类构造方法完成依赖注入,使用的是标签中的元素
在xml中添加bean,使用构造器注入属性值,使用value属性进行参数值的注入
配置文件spring-di.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--使用构造器注入值为123的name-->
<bean id="person" class="biuaxia.bean.Person">
<property name="name" value="123"/>
</bean>
</beans>
测试文件TestUserConstructorInjection.java
package biuaxia.test;
import biuaxia.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Class Describe:测试使用构造器注入
*
* @author biuaxia
* @date 2018/11/13
* @time 17:40
*/
public class TestUserConstructorInjection {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("spring-di.xml");
Person person = app.getBean("person", Person.class);
System.out.println(person);
}
}
运行结果
Person{name='123'}
如果构造函数存在多个参数时,怎么处理?
多个参数时,把参数传递给构造函数可能会存在歧义
可以使用 index 属性来显式的指定构造函数参数的索引,索引从0开始
修改定义如下:
<!--使用构造器注入值为123的name-->
<bean id="person" class="biuaxia.bean.Person">
<constructor-arg index="0" value="123"/>
<!-- 这里是为了演示加的下面这句,我们的person类只有一个参数哈 -->
<constructor-arg index="1" value="233"/>
</bean>
使用type属性指定参数的类型
注意:基本类型有包装类型需要进行区分
修改< bean >定义如下:
<!--使用构造器注入值为123的name-->
<bean id="person" class="biuaxia.bean.Person">
<constructor-arg index="0" type="java.lang.String" value="123"/>
<!-- 这里是为了演示加的下面这句,我们的person类只有一个参数哈 -->
<constructor-arg index="1" type="java.lang.Integer" value="233"/>
</bean>
需要给参数指定一个引用(指向其他bean),使用ref属性
修改xml。添加一个bean定义
<bean id="man" class="biuaxia.bean.Man">
<constructor-arg ref="person"/>
</bean>
测试代码
package biuaxia.test;
import biuaxia.bean.Man;
import biuaxia.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Class Describe:测试使用构造器注入
*
* @author biuaxia
* @date 2018/11/13
* @time 17:40
*/
public class TestUserConstructorInjection {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("spring-di.xml");
Person person = app.getBean("person", Person.class);
System.out.println(person);
Man man = app.getBean("man", Man.class);
System.out.println(man);
}
}
运行结果
Person{name='123'}
Man{person=Person{name='123'}}
使用setter注入
当容器调用一个无参的构造函数或一个无参的静态工厂方法来初始化bean,通过容器在bean 上调用setter设值函数,使用的是标签中的元素 property的name属性指定类的属性名,需要一致,其他与构造器相同
<bean id="" class="" >
<property name="set方法去掉set 然后字母小写" value="字符串值"/>
<property name="set方法去掉set 然后字母小写" ref="对象id"/>
</bean>
使用自动装配
只要在标签中出现 一个属性叫
autowire="值"
这个属性的默认值是no
叫不采用自动注入
其它的取值有byName(以属性的名字和容器中组件的id对应关系)
byType
按照类型去查找,如果同类型的对象有多个 则报错
constructor
参数的个数要严格匹配可以使用<constuctor-arg>
占参数位置但是不能使用
占位置 。优先使用
byName注入,后使用
byType,如果类型有冲突 则报错。
autodetect`早期版本支持,目前的版本不支持了。
注入的内容(装配数据)
1)参数值注入
上面已经讲过可以通过value进行参数值注入,使用ref进行bean对象的注入
2)注入集合
<list>
注入一列值,允许重复
<set>
注入一列值,不允许重复
<map>
注入键(名)值对的集合,名称和值可以是任何类型
<props>
注入键(名)值对的集合,名称和值可以是任何类
例:在biuaxia.bean
包中新建JavaCollection
类如下:
public class JavaCollection {
private List list;
private Map map;
private Properties prop;
//构造方法,setter,getter和toString方法略
}
在Spring配置中定义bean,修改xml,添加bean定义
<bean id="coll" class="biuaxia.bean.JavaCollection">
<property name="list">
<!-- 注入集合 值可重复 set就不举例了-->
<list>
<value>list1</value>
<value>list1</value>
</list>
</property>
<property name="map">
<!-- 注入map -->
<map>
<entry key="二蛋">
<value>18</value>
</entry>
</map>
</property>
<property name="prop">
<!-- 注入properties -->
<props>
<prop key="二黑">男</prop>
</props>
</property>
</bean>
在测试类中新加测试方法test03并测试:
@Test
public void test03(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-di.xml");
JavaCollection collection = ctx.getBean("coll",JavaCollection.class);
System.out.println(collection);
}
查看控制台输出:
JavaCollection [list=[list1, list1], map={二蛋=18}, prop={二黑=男}]
注入Spring表达式
Sprng引入一种跟EL表达式类型语法的Spring表达式,可以读取一个bean对象或者集合中的内容:
#{bean.属性}
在Spring配置中定义bean,修改xml,添加bean定义
<!-- setter方法注入 -->
<bean id="personSet1" class="com.oak.entity.Person">
<property name="age" value="#{personSet.age}"/>
<property name="name" value="#{personSet.name}"/>
</bean>
在测试类中添加test04并测试
@Test
public void test04(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-di.xml");
Person person=ctx.getBean("personSet",Person.class);
System.out.println(person);
Person person1=ctx.getBean("personSet1",Person.class);
System.out.println(person1);
}
查看控制台结果
Person [name=二蛋, age=18]
Person [name=二蛋, age=18]
注入空字符串或者null
""和< null />
就不做案例了
附上原版的学习笔记
- 什么是IOC
- 写出使用 Spring容器的步骤 和 每一步的关键代码
- 写出Spring容器 创建对象的三种方式 和 三种方式对应的配置文件写法
- 写出Spring中 如何对对象进行初始化 如何销毁对象之前调用方法 和 如何延迟实例化
1.什么是DI
DI 就是 Dependence Injection 依赖注入
解决的问题是 组件之间的装配关系问题 DI 是对 IOC一种具体实现
2.DI 的实现 方式
2.1 setter 注入
基于set 方法的注入
<bean id="" class="" >
<property name="set方法去掉set 然后字母小写" value="字符串值"> </property>
<property name="set方法去掉set 然后字母小写" ref="对象id"> </property>
</bean>
2.2 构造器注入
看的是构造方法的参数
3.自动化注入 ----- 自动装配
只要在bean 标签 中出现 一个属性叫 autowire=“值”
这个属性的默认值 是 no 叫 不采用自动注入
其它的取值 有 byName (以属性的名字 和 容器中组件的id 对应关系 )
byType 按照类型去查找 如果同类型的对象有多个 则报错
constructor 参数的个数要严格匹配 可以使用 占参数位置
但是不能使用 占位置 。 优先使用 byName 注入 后使用 byType 如果类型
有冲突 则报错。
autodetect 早期版本支持 目前的版本不支持了。
4.bean 参数注入 ---- 简单数据的注入
基本类型的数据 和 字符串
<bean id="msg" class="com.xdl.bean.MsgBean">
<property name="title">
<value>中午吃什么</value>
</property>
<property name="length" value="123"></property>
</bean>
5.bean 参数注入 ---- 集合数据的注入
java 中的 List 对应配置文件 中的 标记
<list>
<value>值</value>
<value>值2</value>
</list>
java中的 Set 对应配置文件中的 标记
<set>
<value>值</value>
<value>值2</value>
</set>
java 中的 Map 对应配置文件中的
<map>
<entry key="" value="" />
<entry key="" value="" />
</map>
java 中的 Properties 对应配置文件中的 标记
<props>
<prop key="">文本值</prop>
<prop key="">文本值</prop>
</props>
6.集合的单独定义 并被引入
<list> -------<util:list>
<set> -------<util:set>
<map> ----- <util:map>
<props> ------ <util:properties>
记得给单独定义的集合 加上id 在 属性标签 使用 ref 属性 来引用中引用这个id值