2.4 实验三:依赖注入之setter注入
依赖注入(DI):是IOC的一种具体的实现方式
IOC是从当前资源获取的角度来说,我们原先来主动获取,现在是被动的接受,原来是直接new ,现在我需要 我们只需要把我们依赖的对象设置成相对应的方法,比如set方法 有参构造 然后以我们设置好的方法 来接受spring为我们所注入对象
比如:
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
public Student() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
Student里面的id,name age sex ,我们就说Student依赖于id,name age sex 属性(对象依赖于属性),那么我们就可以在IOC容器中,为我们所依赖的属性来进行赋值
所以依赖注入就是为我们类的属性进行赋值的一个过程
package com.atguigu.spring.pojo;
public class Student implements Person {
private Integer sid;
private String sname;
private Integer age;
private String gender;
public Student() {
}
public Student(Integer sid, String sname, Integer age, String gender) {
this.sid = sid;
this.sname = sname;
this.age = age;
this.gender = gender;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
<!-- property 标签:通过组件类的 setXxx() 方法给组件对象设置属性 --><!-- name 属性:指定属性名(这个属性名是 getXxx() 、 setXxx() 方法定义的,和成员变量无关)--><!-- value 属性:指定属性值 -->依赖注入的第一种方法,叫做 setter 注入,其实就是当前为属性,为成员变量,提前设置好的一些方式,通过这些方式 比如set 构造器 等方式为成员变量赋值 的一个过程,
<?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="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
<!-- <bean id="studentTwo" class="com.atguigu.spring.pojo.Student"></bean>-->
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student">
<!--
property:通过成员变量的set方法进行赋值
name:设置需要赋值的属性名(和set方法有关)
value:设置为属性所赋的值
-->
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
<property name="age" value="23"></property>
<property name="gender" value="男"></property>
</bean>
</beans>
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentTwo", Student.class);
System.out.println(student);
}
2.5 实验四:依赖注入之构造器注入
构造器注入:通过构造器的有参构造来为当前的成员变量赋值
在一个类中为成员变量赋值的于种方式:set方法 和有参构造
package com.atguigu.spring.pojo;
public class Student implements Person {
private Integer sid;
private String sname;
private Integer age;
private String gender;
public Student() {
}
public Student(Integer sid, String sname, Integer age, String gender) {
this.sid = sid;
this.sname = sname;
this.age = age;
this.gender = gender;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>
@Testj
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
// Student student = ioc.getBean("studentTwo", Student.class);
Student student = ioc.getBean("studentThree", Student.class);
System.out.println(student);
}
注意:constructor-arg 标签还有两个属性可以进一步描述构造器参数:index 属性:指定参数所在位置的索引(从 0 开始)name 属性:指定参数名
原来
public Student(Integer sid, String sname, Integer age, String gender) {
this.sid = sid;
this.sname = sname;
this.age = age;
this.gender = gender;
}
现在
public Student(Integer sid, String sname, String gender, Integer age) {
this.sid = sid;
this.sname = sname;
this.age = age;
this.gender = gender;
}
在设置一个有参构造
public Student(Integer sid, String sname, String gender, Double score) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.score = score;
}
问题:
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
</bean>
24 能够匹配到Integer age 也能够匹配到Double score 24是整型 所以到底匹配哪个有参构造
测试:匹配到Double score
如何匹配到Integer age
解决
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
<constructor-arg value="24" name="age"></constructor-arg>
</bean>
提问:
null 特殊字符 属性是个类类型 或是接口类型 数组 list map集合应该如何赋值
2.6 实验五:特殊值处理
<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>
如果是这样可以吗?
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王王"></property>
<property name="gender" value="null"></property>
</bean>
测试:
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
// Student student = ioc.getBean("studentTwo", Student.class);
// Student student = ioc.getBean("studentThree", Student.class);
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student);
}
测试如下:加方法.getGender().toString()如果没有报错 那就说明是当前的null是字符的null
但是如果null对象是空对象的话,变变成调用null.toString() ,所以要为某个成员变量赋值为null 以下这个地方不能写null
正确写法:
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王王"></property>
<property name="gender">
<null></null>
</property>
</bean>
双标签里面没内容时可以设置成单标签
或
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王王"></property>
<property name="gender">
<null />
</property>
</bean>
测试:
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
// Student student = ioc.getBean("studentTwo", Student.class);
// Student student = ioc.getBean("studentThree", Student.class);
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student.getGender().toString());
}
发现报了空指针 空指针对应行所操作的对象一定null student不为null 所以为空的是getGender()
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<!-- <property name="sname" value="王五"></property>-->
<property name="sname" value="<王五>"></property>
<property name="gender">
<null />
</property>
</bean>
测试:
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student);
}
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<!-- <property name="sname" value="王五"></property>-->
<!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 -->
<!-- 解决方案一:使用XML实体来代替 -->
<!-- <property name="sname" value="<王五>"></property>-->
<!-- 解决方案二:使用CDATA节 -->
<!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
<!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
<!-- 所以CDATA节中写什么符号都随意 -->
<!--
<:<
>:>
CDATA节其中的内容会原样解析<![CDATA[...]]>
CDATA节是xml中一个特殊的标签,因此不能写在一个属性中
-->
<!--<property name="sname" value="<王五>"></property>-->
<property name="sname">
<value><![CDATA[<王五>]]></value>
</property>
<property name="gender">
<null />
</property>
</bean>
测试
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student);
}
以下是自学群 如果有自学的同学 可以加群讨论(禁广告)
群不是引流群 不是引流群 不是引流群
也不是为了任何的利益 只是为了让大家学习上有个讨论的地方
同时我也是一个菜鸟欢迎大神们可以多加指导(群里已经有很多大神 也多欢迎更多大神进群给小白一点指导哈哈哈哈)