【IOC/DI核心概念、入门案例】


一、Spring系统架构和学习路线

Spring Framework的5版本目前没有最新的架构图,而最新的是4版本,所以接下来主要研究的是4的架构图。
框架1

学习路线:
在这里插入图片描述

二、Spring核心概念

使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象

2.1 IOC、IOC容器、Bean、DI

2.1.1 IOC(Inversion of Control)控制反转

  • 控制反转:使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部。
  • Spring 提供了一个容器,称为 IOC 容器 ,用来充当 IOC 思想中的 " 外部",IOC 思想中的 别人 [ 外部 ] 指的就是 Spring 的 IOC 容器。
  • IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象,被创建或被管理的对象在 IOC 容器中统称为 Bean , IOC 容器中放的就是一个个的 Bean 对象。
  • 当 IOC 容器中创建好 service 和 dao对象后,程序还不能正确执行,因为 service 运行需要依赖 dao对象,但是 service 对象和 dao对象没有任何关系,也就是说要绑定 service 和 dao对象之间的关系,绑定关系就要用到 DI。

2.1.2 DI(Dependency Injection)依赖注入

  • 依赖注入:在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入(业务层要用数据层的类对象,以前是自己new的,现在自己不new了,靠别人[外部其实指的就是IOC容器]来给注入进来)
    在这里插入图片描述

2.2 核心概念小结

介绍完Spring的IOC和DI的概念后,我们会发现这两个概念的最终目标就是:充分解耦,具体实现靠:

  • 使用IOC容器管理bean(IOC)
  • 在IOC容器内将有依赖关系的bean进行关系绑定(DI)
  • 最终结果为:使用对象时不仅可以直接从IOC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

三、入门案例

3.1 、IOC入门案例

***理解原理,实际开发不会用到!***1
分析(1)Spring 是使用容器来管理 bean 对象的,那么管什么 ?
主要管理项目中所使用到的类对象,比如(Service和Dao)
(2) 如何将被管理的对象告知 IOC 容器 ?
使用配置文件
(3) 被管理的对象交给 IOC 容器,要想从容器中获取对象,就先得思考如何获取到 IOC 容器 ?
Spring框架提供相应的接口
(4)IOC 容器得到后,如何从容器中获取 bean?
调用Spring框架提供对应接口中的方法
具体步骤在这里插入图片描述
实现步骤1:创建Maven项目
在这里插入图片描述
步骤2:添加Spring依赖的jar包
在这里插入图片描述
步骤3:添加案例中需要的
创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
在这里插入图片描述
步骤4:添加spring配置文件
resources下添加spring配置文件applicationContext.xml,并完成bean的配置
步骤5:在配置文件中完成bean的配置
在这里插入图片描述
步骤6:获取IOC容器
在这里插入图片描述
步骤7:从容器中获取对象进行方法调用
在这里插入图片描述
步骤8:运行程序
在这里插入图片描述

3.2 、DI入门案例

***理解原理,实际开发不会用到!***1
分析1、要想实现依赖注入,必须要基于IOC管理Bean
2、Service中使用new形式创建的Dao对象需要删除掉,最终要使用IOC容器中的bean对象
3、Service 中需要的 Dao 对象如何进入到 Service 中?
在 Service中提供方法,让Spring的IOC容器可以通过该方法传入bean对象
4、Service 与 Dao 间的关系如何描述?
使用配置文件
具体步骤在这里插入图片描述
实现步骤 1: 去除代码中的 new
在 BookServiceImpl 类中,删除业务层中使用 new 的方式创建的 dao 对象
在这里插入图片描述
步骤 2: 为属性提供 setter 方法
在 BookServiceImpl 类中 , 为 BookDao 提供 setter 方法
在这里插入图片描述
步骤 3: 修改配置完成注入
在这里插入图片描述
注意:两个bookDao含义不同,差别如图:
在这里插入图片描述
步骤 4: 运行程序
在这里插入图片描述

3.3 、IOC相关内容——Bean

***理解原理,实际开发不会用到配置文件,更多使用注解开发!***1

3.3.1 Bean的基础配置

1、Bean的id与class属性
<bean id="" class=""/>
  • id: bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一

  • class: bean的类型,即配置的bean的全路径类名

2、Bean的name属性
3、Bean的scope配置
  • (1)单例(默认)——singleton
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="singleton"/>

单例的意思就是,同一个bean获取两次,将对象打印到控制台,打印出的地址值完全一致。

默认bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高。

  • (2)非单例——prototype
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>
总结

哪些 bean 对象适合交给容器进行管理(即单例) ?

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象
    哪些 bean 对象不适合交给容器进行管理(即非单例) ?
  • 封装实例的域对象,因为会引发线程安全问题,所以不适合

3.3.2 Bean的实例化

  • 第一种:构造方法实例化(常用)

结论:Spring底层使用的是类的无参构造方法,并且能访问到类中的私有构造方法,显而易见,Spring底层用的是反射

  • 第二种:静态工厂实例化(*)

  • 第三种:FactoryBean(实用)

1、准备一个 UserDao 和UserDaoImpl类
在这里插入图片描述
在这里插入图片描述
2、创建一个 UserDaoFactoryBean 的类,实现FactoryBean接口,重写接口的方法
在这里插入图片描述
3、在 Spring 的配置文件中进行配置

<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>

4、创建一个运行类AppForInstanceUser
在这里插入图片描述
5、运行
在这里插入图片描述
注意:该方法设置的对象默认也为单例,单例/非单例的具体实现如下:
在UserFactoryBean类中实现接口中的方法isSingleton():

public boolean isSingleton() {
    return false;
}

3.4 DI相关内容——DI依赖注入

***理解原理,实际开发不会用到配置文件,更多使用注解开发!***1

3.4.1 Setter注入

对于引用数据类型使用的是<property name=" " ref=" "/>
对于简单数据类型使用的是<property name=" " value=" "/>

(1)引用类型注入
上面的例子就是引用类型注入,例如现在有BookDao,UserDao接口(不再赘述),有BookServiceImpl实现类,代码如下:

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;
 
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
 
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
 
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

现在,我们在配置文件中使用property标签注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
    <property name="userDao" ref="userDao"/>
</bean>

(2)简单类型注入

BookDaoImpl实现类如下:

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;
 
    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }
 
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
 
    public void save() {
        System.out.println("book dao save
..."+databaseName+", "+connectionNum);
    }
}

现在,我们在配置文件中使用property标签注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <property name="databaseName" value="mysql"/>
    <property name="connectionNum" value="10"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
    <property name="userDao" ref="userDao"/>
</bean>

3.4.2 构造器注入(*)

引用数据类型 <constructor-arg name="" index="" type="" ref=""/>
简单数据类型 <constructor-arg name="" index="" type="" value=""/>
        实际开发中,更推荐使用Setter注入,故构造器注入略

3.4.3 自动配置(*)

方式:

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用自动装配

3.4.4 集合注入

在BookDaoImpl实现类中,不再是引用类型和简单数据类型,而是集合类型,常见的集合类型有:

  • 数组
  • List
  • Set
  • Map
  • Properties
    在配置文件中,注入数组数据类型如下:
<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

文章转载自:https://blog.csdn.net/qq_45832961/article/details/129015631

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值