【补充】Spring 第一天 DI注入的三种方式和数据的装配方式

文章目录

  • 哪三种方式?
    • 准备工作
    • 使用构造器注入
      • 如果构造函数存在多个参数时,怎么处理?
      • 使用type属性指定参数的类型
      • 需要给参数指定一个引用(指向其他bean),使用ref属性
    • 使用setter注入
    • 使用自动装配
    • 注入的内容(装配数据)
      • 1)参数值注入
      • 2)注入集合
        • 注入Spring表达式
        • 注入空字符串或者null
  • 附上原版的学习笔记

哪三种方式?

  1. 使用构造器注入
  2. 使用setter注入
  3. 使用自动装配

准备工作

  • 配置文件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


<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">
    
    <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开始
修改定义如下:


<bean id="person" class="biuaxia.bean.Person">
	<constructor-arg index="0" value="123"/>
	
	<constructor-arg index="1" value="233"/>
bean>

使用type属性指定参数的类型

注意:基本类型有包装类型需要进行区分
修改< bean >定义如下:


<bean id="person" class="biuaxia.bean.Person">
	<constructor-arg index="0" type="java.lang.String" value="123"/>
	
	<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参数的个数要严格匹配可以使用占参数位置但是不能使用占位置 。优先使用byName 注入,后使用byType,如果类型有冲突 则报错。autodetect`早期版本支持,目前的版本不支持了。

注入的内容(装配数据)

1)参数值注入

上面已经讲过可以通过value进行参数值注入,使用ref进行bean对象的注入

2)注入集合

注入一列值,允许重复
注入一列值,不允许重复
注入键(名)值对的集合,名称和值可以是任何类型
注入键(名)值对的集合,名称和值可以是任何类
例:在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">
		
		<list>
		<value>list1value>
		<value>list1value>
		list>
	property>
	<property name="map">
		
		<map>
		<entry key="二蛋">
		<value>18value>
		entry>
		map>
	property>
	<property name="prop">
		
		<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定义


<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 />
就不做案例了

附上原版的学习笔记

  1. 什么是IOC
  2. 写出使用 Spring容器的步骤 和 每一步的关键代码
  3. 写出Spring容器 创建对象的三种方式 和 三种方式对应的配置文件写法
  4. 写出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>值2value>
list>     

java中的 Set 对应配置文件中的 标记

<set>
   <value>value>
   <value>值2value>
set>

java 中的 Map 对应配置文件中的 标记

<map>
   <entry key="" value="" />
   <entry key="" value="" />
map> 

java 中的 Properties 对应配置文件中的 标记

<props>
    <prop key="">文本值prop> 
    <prop key="">文本值prop> 
props>

6.集合的单独定义 并被引入

-------
-------
-----
------
记得给单独定义的集合 加上id 在 属性标签 使用 ref 属性 来引用中引用这个id值

你可能感兴趣的:(Spring学习)