详解Spring的Ioc与DI

本文详细介绍了Spring框架的核心概念:控制反转(IoC)和依赖注入(DI)。阐述了Spring如何通过工厂模式管理对象创建,以及对象的生命周期和作用范围。并通过示例展示了不同类型的依赖注入方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring 的体系结构

在这里插入图片描述

1.控制反转-Inversion Of Control

工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:我们在获取对象时,都是采用 new 的方式。是主动的。
在这里插入图片描述

现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
在这里插入图片描述
将创建对象的权利交给框架:
在这里插入图片描述

<!--spring对bean的管理细节
    1.创建bean的三种方式
    2.bean对象的作用范围
    3.bean对象的生命周期
-->
<!--创建bean的三种方式-->
<!--第一种方式
    第一种方式 使用默认构造函数创建,
    在spring的配置文件中使用bean标签,配以class和id属性,且没有其他属性和标签时,
    采用的是默认构造函数创建的bean对象,此时,类中没有默认构造函数,则bean对象无法创建

    <bean id="accountService" class="com.maxwell.service.impl.AccountServiceImpl"></bean>
-->
<!--第二种方式,使用普通工厂的方法创建对象,(使用某个类中方法创建对象,然后存入spring容器)-->
<!--<bean id="instanceFactory" class="com.maxwell.factory.InstanceFactory"></bean>-->
<!--<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->
<!--第三种方式,使用工厂中的静态方法创建对象(使用某个类中静态方法创建对象,然后存入spring容器)-->

<!--<bean id="accountService" class="com.maxwell.factory.StaticFactory" factory-method="getAccountService"></bean>-->

<!--2.bean对象的作用范围
    bean标签的scope属性:
         作用:指定bean的作用范围
            取值:
                singleton  单例的 (默认值)
                prototype  多例的
                request    作用于web应用的请求范围
                session    作用于web应用的会话范围
                global-session  作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session.
-->
<!--3.bean对象的生命周期
    单例对象:
    出生:当创建容器时对象出生
    活着:只要容器还在,对象就一直活着
    死亡:容器销毁,对象消亡
 总结:单例对象的生命周期和容器相同
多例对象:
    出生:当使用对象时spring框架才为我们创建对象
    活着:对象只要是我们在使用过程中就一直活着
    死亡:当对象长时间不用,或者没有对象引用时,由JAVA垃圾回收线程回收

-->

2.依赖注入( Dependency Injection)

<?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">
    
<!--spring的依赖注入:
    依赖注入:
    Dependency Injection
    IOC的作用:
        降低程序间的耦合
    依赖关系间的管理:以后都交给Spring来管理
    在当前类要用到其他类的对象,由Spring为我们提供,我们只要在配置文件中说明即可
    依赖关系的维护:
        就称之为依赖注入
    依赖注入:
          能注入的数据有三类
            1.基本类型和string
            2.其他bean类型(在配置文件中或注解配置过的bean)
            3.复杂类型/集合类型
    注入的方式有三种:
            1.通过构造函数提供
            2.通过set方法提供
            3.使用注解提供

-->
<!--1.通过构造函数提供
    使用constructor-arg标签
    出现的位置:在bean标签的内部
        标签中的属性:
        type:用于指定要注入的数据类型,该数据类型也就是构造函数中某个参数的数据类型
        name:用于指定构造函数中指定名称的参数赋值
        index: 用于指定要注入的数据给构造函数中指定位置的参数赋值。索引位置从0开始
        =======================以上三个用于给构造函数中哪个参数赋值==========================
        value:用于提供基本数据类型和String类型的数据
        ref:用于指定其它的bean类型的数据,它指的是就是在Spring核心容器中出现过的对象

        优势:
            在获取bean对象时,注入数据是必须的,否则无法创建对象
        弊端:
            改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据时,也必须提供
-->
<bean id="accountService" class="com.maxwell.service.impl.AccountServiceImpl">
    <!--<constructor-arg type="java.lang.String" value="test"></constructor-arg>-->
    <constructor-arg name="name" value="JACK"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="new"></constructor-arg>
</bean>

<!--配置一个日期对象-->
<bean id="new" class="java.util.Date"></bean>

<!--2.通过set方法注入         -------》》更常用的方式注入
    涉及的标签:property
    出现的位置:bean标签的内部
    标签中的属性:
        name: 用于指定注入set方法名称
        value: 用于提供基本数据类型和String类型的数据
        ref:用于指定其它的bean类型的数据,它指的是就是在Spring核心容器中出现过的对象
        优势: 
        		创建对象时没有明确的限制,可以直接使用默认构造函数
        弊端:
        		如果某个成员必须有值,则获取对象是有可能set方法没有执行
-->
<bean id="accountService2" class="com.maxwell.service.impl.AccountServiceImpl2">
    <property name="name" value="Marry"></property>
    <property name="age" value="20"></property>
    <property name="birthday" ref="new"></property>
</bean>


<!--复杂类型的注入/集合类型数据的注入
    用于给List结构注入的标签:
        list  set  array
    用于给map结构注入的标签有:
        map  props
        结构相同,标签可以互换
 -->
<bean id="accountService3" class="com.maxwell.service.impl.AccountServiceImpl3">
    <property name="myStrs">
        <array>
            <value>111</value>
            <value>222</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </set>
    </property>
    <property name="myMap">
        <map>
            <entry key="test1" value="aaa"></entry>
            <entry key="test2" value="bbb"></entry>
            <entry key="test3" value="ccc"></entry>
        </map>
    </property>
    <property name="props">
        <map>
            <entry key="testA" value="123"></entry>
            <entry key="testB" value="456"></entry>
        </map>
    </property>
</bean>

重点:基于注解的IOC

* 曾经XML的配置:
 *  <bean id="accountService" class="com.maxwell.service.impl.AccountServiceImpl"
 *        scope=""  init-method="" destroy-method="">
 *      <property name=""  value="" | ref=""></property>
 *  </bean>
 * 解释:spring在解析xml配置文件时,会根据class属性,也即拿到类的全限定类名,反射创建对象,
 * 存入spring的IOC容器,spring的IOC容器是一个map结构,key是bean的id,value是我们创建的对象。
 * 
 *现在基于注解:
 * 用于创建对象的
 *      他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的
 *      @Service:
 *          作用:用于把当前类对象存入spring容器中
 *          属性:
 *              value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
 * @Service(value="accountService")
 * //@Scope("prototype")
 * public class AccountServiceImpl implements IAccountService {
 *    }
 *      @Controller:一般用在表现层
 *      @Service:一般用在业务层
 *      @Repository:一般用在持久层
 *      以上三个注解他们的作用和属性与Component是一模一样。
 *      他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
 * 
 * 用于改变作用范围的
 *      他们的作用就和在bean标签中使用scope属性实现的功能是一样的
 *      @Scope
 *          作用:用于指定bean的作用范围
 *          属性:
 *              value:指定范围的取值。常用取值:singleton prototype
 *
 * 和生命周期相关 了解
 *      他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的
 *      PreDestroy
 *          作用:用于指定销毁方法
 *      PostConstruct
 *          作用:用于指定初始化方法

1.Spring的ioc是一个map结构,如下图所示,key是string类型,value是object类型。
我们在使用@Autowired注解,当有多个类型匹配时 ,在自动按照类型注入的基础上按照变量名称前往springIoc容器查找。
2.我们可以使用@Qualifier注解用于指定注入的bean的id,注意此注解必须配合@Autowired注解使用
3.@ Resource注解
作用:直接按照bean的id注入。它可以独立使用
属性: name:用于指定bean的id。
4.以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。另外,集合类型的注入只能通过XML来实现。

在这里插入图片描述
@Autowired
自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

@Qualifier
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用
属性:value:指定 bean 的 id。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值