Spring IOC/DI简介

目录

第1章 Spring 概述

1.1.1 spring 是什么

1.1.2 Spring 的发展历程

1.1.3 spring 的优势

1.1.4 spring 的体系结构

1.1.5 spring 的生态系统

第2章 IoC 的概念和作用

2.1 程序的耦合和解耦

2.1.1 什么是程序的耦合【了解】

2.1.2 解决程序耦合的思路

2.1.3 工厂模式解耦

2.1.4 控制反转-Inversion Of Control

第3章 SpringIOC 解决程序耦合

3.1 案例的前期准备

 3.2 基于 XML 的配置

3.3 基于XML的 IOC 细节

3.4 spring 的依赖注入


第1章 Spring 概述

1.1.1 spring 是什么

        Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

1.1.2 Spring 的发展历程

1997 年 ,IBM 提出了 EJB 的思想

1998 年,SUN 制定开发标准规范 EJB1.0

1999 年,EJB1.1 发布

2001 年,EJB2.0 发布

2003 年,EJB2.1 发布

2006 年,EJB3.0 发布

Rod Johnson(spring 之父)

Expert One-to-One J2EE Design and Development(2002)

阐述了 J2EE 使用 EJB 开发设计的优点及解决方案

Expert One-to-One J2EE Development without EJB(2004)

阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏形)

2017 年 9 月份发布了 spring 的最新版本 spring 5.0 通用版(GA)

1.1.3 spring 的优势

方便解耦,简化开发

        通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

AOP 编程的支持

        通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付

声明式事务的支持

        可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。

方便程序的测试

        可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架

        Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(SpringMVC、Mybatis、Hessian、Quartz 等)的直接支持。

降低 JavaEE API 的使用难度

        Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

Java 源码是经典学习范例

        Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以 及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

1.1.4 spring 的体系结构

Spring核心框架体系结构-阿里云开发者社区

1.1.5 spring 的生态系统

 

第2章 IoC 的概念和作用

2.1 程序的耦合和解耦

2.1.1 什么是程序的耦合【了解】

        耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性)。耦合性存在于各个领域,而非软件设计中独有的,但是我们只讨论软件工程中的耦合。 在软件工程中,耦合指的就是就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。

它有如下分类:

(1)内容耦合,当一个模块直接修改或操作另一个模块的数据时,或一个模块不通过正常入口而转入另一个模块时,这样的耦合被称为内容耦合。内容耦合是最高程度的耦合,应该避免使用之。

(2)公共耦合,两个或两个以上的模块共同引用一个全局数据项,这种耦合被称为公共耦合。在具有大量公共耦合的结构中,确定究竟是哪个模块给全局变量赋了一个特定的值是十分困难的。

(3)外部耦合 ,一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息,则称之为外部耦合。

(4)控制耦合 ,一个模块通过接口向另一个模块传递一个控制信号,接受信号的模块根据信号值而进行适当的动作,这种耦合被称为控制耦合。

(5)标记耦合 ,若一个模块 A 通过接口向两个模块 B 和 C 传递一个公共参数,那么称模块 B 和 C 之间存在一个标记耦合。

(6) 数据耦合,模块之间通过参数来传递数据,那么被称为数据耦合。数据耦合是最低的一种耦合形式,系统中一般都存在这种类型的耦合,因为为了完成一些有意义的功能,往往需要将某些模块的输出数据作为另一些模块的输入数据。

(7) 非直接耦合 ,两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。

总结:

        耦合是影响软件复杂程度和设计质量的一个重要因素,在设计上我们应采用以下原则:如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,尽量避免使用内容耦合

2.1.2 解决程序耦合的思路

演示:以耦合度逐步降低的方式实现JDBC连接数据库操作

2.1.3 工厂模式解耦

演示:以解耦方式维护三层之间的依赖关系

提示:把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。 那么,这个读取配置文件,创建和获取三层对象的类就是工厂。

2.1.4 控制反转-Inversion Of Control

上一小节解耦的思路有 2 个问题:

1、存哪去?

        分析:由于我们是很多对象,肯定要找个集合来存;这时候有 Map 和 List 供选择,在应用加载时,创建一个 Map,用于存放三层对象, 我们把这个 map 称之为容器

2、还是没解释什么是工厂?

 工厂就是负责给我们从容器中获取指定对象的类,这时候我们获取对象的方式发生了改变。

原来: 我们在获取对象时,都是采用 new 的方式,是主动的

现在: 我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象,是被动的

这种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。

第3章 SpringIOC 解决程序耦合

3.1 案例的前期准备

3.1.1 准备 spring 的开发包

  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.6</version>
  </dependency>

 3.2 基于 XML 的配置

3.2.1 第一步:添加坐标

3.2.2 第二步:在类的根路径下创建一个任意名称的 xml 文件

3.2.3 第三步:让 spring 管理资源,在配置文件中配置 service 和 dao

<!-- 
	bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中
 		id 属性:对象的唯一标识。
 		class 属性:指定要创建对象的全限定类名
-->
<!-- 配置 service --> 
<bean id="userService" class="com.apesource.service.UserServiceImpl">
</bean>
<!-- 配置 dao -->
<bean id="userDao" class="com.apesource.dao.UserDaoImpl"></bean>

3.2.4 测试配置是否成功

public static void main(String[] args) {
        //1.创建spring核心对象并加载主配置文件
        ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("beans.xml");
        //2.向spring容器索要对象
        IUserService service = (IUserService)applicationContext.getBean("userService");
        IUserDao dao = (IUserDao)applicationContext.getBean("userDao");
        //3.调用方法
        service.insert();
        dao.insert();
}

3.3 基于XML的 IOC 细节

3.3.2 BeanFactory 和 ApplicationContext 的区别

BeanFactory 和 ApplicationContext 的区别:

1.BeanFactory 才是 Spring 容器中的顶层接口,ApplicationContext 是它的子接口;

2.创建对象的时间点不一样

ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。

BeanFactory:什么使用什么时候创建对象。

3.3.3 IOC 中 bean 标签和管理对象细节

3.3.3.1 bean 标签

作用:

用于配置对象让 spring 来创建的默认情况下它调用的是类中的无参构造函数;如果没有无参构造函数则不能创建成功。

属性:

id: 给对象在容器中提供一个唯一标识,用于获取对象。

class: 指定类的全限定类名用于反射创建对象,默认情况下调用无参构造函数。

scope: 指定对象的作用范围。

singleton:默认值,单例的

prototype:多例的

request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中

session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中

global session:全局会话域中

init-method:指定类中的初始化方法名称。

destroy-method:指定类中销毁方法名称。

3.3.3.2 bean 的作用范围和生命周期

单例对象:scope="singleton"

一个应用只有一个对象的实例,它的作用范围就是整个引用。

生命周期:

对象出生:当应用加载,创建容器时,对象就被创建了。

对象活着:只要容器在,对象一直活着。

对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

多例对象:scope="prototype"

每次访问对象时,都会重新创建对象实例。

生命周期:

对象出生:当使用对象时,创建新的对象实例。

对象活着:只要对象在使用中,就一直活着。

对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了

3.3.3.3 实例化 Bean 的三种方式

第一种方式:使用默认无参构造函数

第二种方式:spring 管理静态工厂-使用静态工厂的方法创建对象

第三种方式:spring 管理实例工厂-使用实例工厂的方法创建对象

3.4 spring 的依赖注入

3.4.1 依赖注入的概念

依赖注入:Dependency Injection 它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法,那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了,简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

3.4.2 构造函数注入

<!-- 构造注入
	要求:
		类中需要提供一个对应参数列表的构造函数;
	涉及的标签:
		constructor-arg
	属性:
		index:指定参数在构造函数参数列表的索引位置
		type:指定参数在构造函数中的数据类型
		name:指定参数在构造函数中的名称 用这个找给谁赋值
		=======上面三个都是找给谁赋值,下面两个指的是赋什么值的==============
		value:它能赋的值是基本数据类型和 String 类型
		ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
-->

3.4.3 set 方法注入

<!-- set注入
	要求:
		类中需要提供一个对应属性的set方法;
	涉及的标签:
		property
	属性:
  	name:找的是类中 set 方法后面的部分
  	ref:给属性赋值是其他 bean 类型的
  	value:给属性赋值是基本数据类型和 string 类型的
  	(实际开发中,此种方式用的较多)
-->

3.4.4 p 名称空间注入数据(本质调用 set 方法)不推荐使用

<!-- 
此种方式是通过在 xml 中导入 p 名称空间,使用 p:propertyName 来注入数据,
它的本质仍然是调用类中的set 方法实现注入功能
-->
<beans xmlns="http://www.springframework.org/schema/beans"
 	xmlns:p="http://www.springframework.org/schema/p"
  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="user" class="com.apesource.pojo.User" p:uname="王五" p:age="18"/>

</beans>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

‏猿究院Sublate

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值