【Spring】Spring对IoC的实现

简介: 【Spring】Spring对IoC的实现

根据 【动力节点】最新Spring框架教程,全网首套Spring6教程,跟老杜从零学spring入门到高级 以及老杜的原版笔记 https://www.yuque.com/docs/share/866abad4-7106-45e7-afcd-245a733b073f?# 《Spring6》 进行整理, 文档密码:mg9b


Spring 相关文章整理汇总归纳于:https://www.yuque.com/u27599042/zuisie


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在装配方面还是比较健壮的
相关文章
|
8月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
528 26
|
5月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
10月前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
200 69
|
7月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
10月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
10月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
147 21
|
10月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
238 12
|
10月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
219 2
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
635 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
750 1
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码