根据 【动力节点】最新Spring框架教程,全网首套Spring6教程,跟老杜从零学spring入门到高级 以及老杜的原版笔记 https://www.yuque.com/docs/share/866abad4-7106-45e7-afcd-245a733b073f?# 《Spring6》 进行整理, 文档密码:mg9b文章来源:https://www.toymoban.com/news/detail-617461.html
Spring 相关文章整理汇总归纳于:https://www.yuque.com/u27599042/zuisie文章来源地址https://www.toymoban.com/news/detail-617461.html
IoC 控制反转
- 控制反转是一种思想。
- 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。
- 控制反转,反转的是什么?
- 将对象的创建权利交出去,交给第三方容器负责。
- 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
- 控制反转思想的实现:DI(Dependency Injection,依赖注入)
依赖注入
- 依赖注入实现了控制反转的思想。
- Spring通过依赖注入的方式来完成Bean管理的。
- Bean管理:Bean对象的创建,以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)。
- 依赖注入:
- 依赖指的是对象和对象之间的关联关系。
- 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。
- 依赖注入常见的实现方式包括两种:
- 第一种:set注入
- 第二种:构造注入
set 注入
- set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。
- 这种方式要求属性必须对外提供set方法。
set 注入的使用
public class UserDao {
// 获取本类的日志记录器
private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
public void insert(){
// 使用一下log4j2日志框架
logger.info("数据库正在保存用户信息。");
}
}
public class VipDao {
// 获取本类的日志记录器
private static final Logger logger = LoggerFactory.getLogger(VipDao.class);
public void insert(){
logger.info("正在保存Vip信息!!!!");
}
}
public class UserService {
private UserDao userDao;
private VipDao vipDao;
public void setAbc(VipDao vipDao){
this.vipDao = vipDao;
}
// set注入,必须提供一个set方法。
// Spring容器会调用这个set方法,来给userDao属性赋值。
// 我自己写一个set方法,不使用IDEA工具生成的。不符合javabean规范。
// 至少这个方法是以set单词开始的。前三个字母不能随便写,必须是“set"
/*public void setMySQLUserDao(UserDao xyz){
this.userDao = xyz;
}*/
// 这个set方法是IDEA工具生成的,符合javabean规范。
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void saveUser(){
// 保存用户信息到数据库
userDao.insert();
vipDao.insert();
}
}
<?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">
<!--配置dao-->
<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
<!--配置service-->
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<!-- 想让Spring调用对应的set方法,需要配置property标签 -->
<!-- name属性值:set方法的方法名,去掉set,然后把剩下的单词首字母变小写。-->
<!-- ref翻译为引用,英语单词:referencesref,其属性值指定的是要注入的bean的id。-->
<!--<property name="mySQLUserDao" ref="userDaoBean"/>-->
<!--set方法起名的时候,不要为难自己,按照规范来。所以一般情况下name位置写属性名就行了。-->
<property name="userDao" ref="userDaoBean"/>
<!--<property name="vipDao" ref="vipDaoBean"/>-->
<!-- name属性值:set方法的方法名,去掉set,然后把剩下的单词首字母变小写。 -->
<property name="abc" ref="vipDaoBean"/>
</bean>
<bean id="vipDaoBean" class="com.powernode.spring6.dao.VipDao"/>
</beans>
set 注入分析
- set 注入的实现原理:
- 通过property标签获取到属性名:userDao
- 通过属性名推断出与该属性对应的set方法的方法名:setUserDao
- 通过反射机制调用setUserDao()方法给属性赋值
- 一般情况下,set方法的命名符合JavaBean规范,property标签的name属性的属性值就是属性名。
- property标签的name属性的属性值是,setUserDao()方法名演变得到的,演变的规律是:
- 去掉set,然后剩下的部分首字母改为小写
- setUsername() 演变为 username
- setPassword() 演变为 password
- setUserDao() 演变为 userDao
- setUserService() 演变为 userService
- property标签的ref属性的属性值是要注入的bean对象的id,通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。
- 装配指的是:创建系统组件之间关联的动作
- 对于property标签来说,ref属性也可以采用标签的方式,不使用ref属性:
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<property name="userDao">
<ref bean="userDaoBean"/>
</property>
</bean>
- 总结:set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。
构造注入
- 核心原理:通过调用构造方法来给属性赋值。
- 与set注入相比,构造注入是在创建对象的同时进行注入,进行属性的赋值,而set注入是在对象创建之后。
public class CustomerService {
private UserDao userDao;
private VipDao vipDao;
public CustomerService(UserDao userDao, VipDao vipDao) {
this.userDao = userDao;
this.vipDao = vipDao;
}
public void save(){
userDao.insert();
vipDao.insert();
}
}
<?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="xxxx" class="com.powernode.spring6.dao.UserDao"/>
<bean id="yyyy" class="com.powernode.spring6.dao.VipDao"/>
<bean id="csBean3" class="com.powernode.spring6.service.CustomerService">
<!--不指定下标,也不指定参数名,让spring自己做类型匹配。-->
<!--这种方式实际上是根据类型进行注入的。spring会自动根据类型来判断把ref注入给相应的参数。-->
<constructor-arg ref="yyyy"/>
<constructor-arg ref="xxxx"/>
</bean>
<bean id="csBean2" class="com.powernode.spring6.service.CustomerService">
<!--根据构造方法参数的名字进行注入。-->
<!-- name属性值为要进行注入的构造函数的参数 -->
<constructor-arg name="vipDao" ref="yyyy"/>
<constructor-arg name="userDao" ref="xxxx"/>
</bean>
<bean id="csBean" class="com.powernode.spring6.service.CustomerService">
<!--构造注入-->
<!--
index属性指定参数下标,第一个参数是0,第二个参数是1,第三个参数是2,以此类推。
ref属性用来指定注入的bean的id
-->
<!--指定构造方法的第一个参数,下标是0-->
<constructor-arg index="0" ref="xxxx"/>
<!--指定构造方法的第二个参数,下标是1-->
<constructor-arg index="1" ref="yyyy"/>
</bean>
</beans>
- 通过构造方法进行注入有三种形式:
- 可以通过下标
- 可以通过参数名
- 也可以不指定下标和参数名,可以类型自动推断。
- Spring在装配方面还是比较健壮的
到了这里,关于【Spring】Spring对IoC的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!