目录
前言
setter注入
使用步骤
demo(案例)
构造器注入
使用步骤
demo(案例)
自动装配
byName
byType
前言
在spring 框架中 loc 容器 帮助我们创建对象,dl 依赖注入主要则是帮助我们具体的使用 创建的对象。我们清楚 对象被使用的应用场景有:
- 某类中作为成员变量
因此 我们知道 Dl 依赖注入 大体上 是解决 一个问题
1 当对象做为类中的成员变量时,我们应该如何为该成员变量 赋值
因此 Dl 依赖注入 有如下图三种方式
setter注入
使用步骤
1 spring配置文件中 使用 property 标签 ,表示每一个 属性信息
2 在目标类中 提供 set 方法
核心标签<property name="?" ref="?">。
注意:
name属性值一定要与使用依赖注入的类的成员变量名相同
ref 属性值是真正传递的对象
demo(案例)
项目准备
整个项目结构
目的
UserServlet 测试类中 当 id=1,name="李华",age=18 ,打印 user 类对象
最终效果展示
spring配置文件
图片展示
spring配置文件代码
<?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 class="fs.service.lmpl.UserServiceImpl" id="userService"><property name="userDao" ref="UserDaoImpl"></property>
</bean><bean id="UserDaoImpl" class="fs.Dao.lmpl.UserDaoImpl">
<!-- <constructor-arg name="user" ref="User"></constructor-arg>--><property name="user" ref="User"></property></bean><bean id="User" class="fs.entity.User"><constructor-arg index="0" value="1"></constructor-arg><constructor-arg index="1" value="李华"></constructor-arg><constructor-arg index="2" value="18"></constructor-arg></bean></beans>
UserDaoImpl 类
图片展示
UserDaoImpl 类代码
java">package fs.Dao.lmpl;import fs.Dao.UserDao;
import fs.entity.User;
public class UserDaoImpl implements UserDao {private User user;// public UserDaoImpl(User user) {
// this.user = user;
// }public void setUser(User user) {this.user = user;}@Overridepublic void add() {System.out.println(user);}}
UserServiceImpl 类 图片展示
UserServiceImpl 类 代码
java">package fs.service.lmpl;import fs.Dao.UserDao;
import fs.Dao.lmpl.UserDaoImpl;
import fs.service.UserService;public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void add() {userDao.add();}}
UserServlet 测试类
java">package fs.web;import fs.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class UserServlet {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");UserService userService = (UserService) context.getBean("userService");userService.add();}
}
运行结果
构造器注入
使用步骤
1 在 spring 配置文件 使用 constructor-arg 标签 表示 构造方法 的参数,参数的传递
2 在某类中 创建目标对象的构造方法
核心标签
<constructor-arg index/name=? value/ref=?></constructor-arg>
提示:value 一般用于 基本数据类型; ref 多用于对象
注意
把之前spring配置文件里面的<property>标签换成<constructor-arg>标签即可。其中属性"ref"的值为依赖注入的类对应标签<bean>所绑定的id即可。
demo(案例)
- 和之前相比需要修改的地方
1 spring配置文件
2 在目标类中,添加 构造方法
效果展示
自动装配
关于自动装配的介绍
- 自动注入需要用到 autowire 属性 ,不需要我们手动在 spring 配置文件 里使用 标签去配置
- autowire 的属性值有 byName 或 byType
- 自动装配的底层逻辑 其实和 setter 注入的方式一样,只是自动装配省略了在 配置文件中专门给 属性添加 property 标签
byName
当 autowire 的属性值 为 byName 时 ,spring 容器在创建对象后 为目标类中的属性 实现自动装配。如spring 容器查看 A 类的所有属性,将已经创建成功的bean【对象】和属性名要求匹配(spring 配置文件的 bean 标签 id 和 类中的属性名相同),并使用set 方法注入
案例演示
springConfig .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 class="fs.exerise04.A" id="a" autowire="byName"></bean><bean class="fs.exerise04.B" id="b"></bean><bean class="fs.exerise04.C" id="c"></bean></beans>
在 A 类提供属性b,c 和 set 方法 进行检验
java">package fs.exerise04;public class A {private B b;private C c;public void setB(B b) {this.b = b;}public void setC(C c) {this.c = c;}public void test (){System.out.println("aaaaaaaa");b.print();c.test();} }
效果展示
发现 : autowire 属性 已经成功和 目标类的属性 各自实现了注入
推论1
bean 标签的 id的属性值 和 类中的 对应的set方法名对应
如 id =a, 对应的setA()
改动的spring 配置文件
<bean class="fs.exerise04.B" id="b1"></bean>
效果展示(未修改前)
提示 NullPointerException表示没有通过set赋值,给目标类的属性
修改 目标类中的对应的set 方法名
java"> public void setB1(B b) {this.b = b;}
效果展示
结论1 :bean 标签的 id的属性值 和 类中的 对应的set方法名相对应
推论2
bean 标签中的 id 不能为大写,即使和 set方法名相对应也会报错
<bean class="fs.exerise04.B" id="Bb"></bean>
目标类中的set方法
效果展示
提示:即使 b 类set方法和 b类bean 标签的id 相对应,也无法成功调用set 方法创建b 类对象
结论2 :bean 标签的 id 都应该小写
byType
当 autowire 的属性值 为 byType 时 ,spring 容器会检查当前 目标类中的属性的 数据类型 和配置文件的bean 标签 进行匹配。如spring 容器查看 A 类的所有属性,将已经创建成功的bean【对象】和各个属性的数据类型相同的一个或多个匹配起来
案例演示
springConfig .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 class="fs.exerise04.A" id="a" autowire="byType"></bean><bean class="fs.exerise04.B" id="Bbb"></bean><bean class="fs.exerise04.C" id="cc"></bean></beans>
在 A 类提供属性b,c 和 set 方法 进行检验
java">package fs.exerise04;public class A {private B b;private C c;public void setBb(B b) {this.b = b;}public void setC(C c) {this.c = c;}public void test (){System.out.println("aaaaaaaa");b.print();c.test();} }
效果展示
发现:即使 id 和 目标类中的set 方法名不一致。但只要 数据类型保持一致
注意 :set 方法注入相同类型的对象在 spring 配置文件只能有一个bean 标签,否则会报错
<bean class="fs.exerise04.B" id="Bbb"></bean><bean class="fs.exerise04.B" id="bb"></bean>