1、程序的耦合与解耦
- 什么是程序的耦合
类之间产生的依赖关系称之为耦合
如原生jdbc操作数据库存在的严重问题:当前类和MySQL的驱动类有很强的的依赖关系,没有驱动类则无法编译,这种依赖关系就叫程序的耦合。
在开发中理想的状态是:尽力做到编译时不依赖,运行时才依赖。
- 解耦的思路
通过反射来注册驱动,好处是,类中不在依赖于具体的驱动类,此时删除MySQL的驱动jar包,依然可以编译,但是不能运行。
还有一个问题是反射类对象的全限定类名字符串是在java类中写死的,一旦要改还是要修改源码,解决这个问题可以使用配置文件配置。
2、控制反转 Inversion of control
解耦的思路:
- 存哪?
在应用加载时,创建一个Map,用来存放对象。这个map称之为容器 - 什么是工厂?
工厂是负责从容器中获取指定对象的类。这时获取对象的方式发生改变。
原来:
获取对象采用new的方式,是主动的。
现在:
获取对象时跟工厂要,工厂负责查找或创建对象,是被动的。
这种被动接收的方式获取对象的思想就是控制反转。它是spring框架的核心之一。作用只有一个:削减计算机程序的耦合。
3、spring中工厂的类结构
-
BeanFactory和ApplicationContext的区别
BeanFactory是spring容器中的顶层接口,ApplicationContext是它的子接口
区别:创建对象的时间点不一样
ApplicationContext:只要一读取配置文件,默认情况下就会创建对象
BeanFactory:什么时候使用什么时候创建对象 -
ApplicationContext接口的实现类
ClassPathXmlApplicationContext:它从类的根路径下加载配置文件(推荐使用)
FileSystemXmlApplicationContext:它从磁盘路径下加载配置文件,配置文件可以在磁盘的任意位置。
4、IOC中bean标签和管理对象细节
- bean标签
作用:用于配置对象让spring来创建,默认情况下调用无参构造函数,如果没有无参构造函数则不能创建成功。
属性:
id:给对象在容器中提供唯一标识。用于获取对象
class:用于指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
singleton:默认值,单例的
prototype:多例的
request:
session:
globalSession:
init-method:指定类中初始化方法名称
destroy-method:指定类中销毁方法名称 - bean的作用范围和生命周期
单例对象:scope=“singleton”
一个应用只有一个对象的实例,它的作用范围就是整个应用
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了
对象活着:只要容器在,对象一直活着
对象死亡:当应用卸载,销毁容器时,对象就被销毁了
多例对象:scope=“prototype”
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例
对象活着:只要对象在使用中,就一直活着
对象死亡:当对象长时间不使用时,被JVM的垃圾回收器回收
5、实例化bean的3种方式
-
第一种方式:使用默认无参构造函数
默认情况下调用无参构造函数创建类对象,如果没有无参构造函数则不能创建成功。 -
第二种方式:spring管理静态工厂-使用静态工厂的方法创建对象
使用静态工厂类的静态方法创建对象,并存入spring容器
id属性:指定bean的id,用于从容器中获取
class属性:指定静态工厂的全限定类名
factory-method属性:指定生产对象的静态方法 -
第三种方式:spring管理实例工厂-使用实例工厂的方法创建对象
先把工厂的创建交给spring来管理
然后在使用工厂的bean来调用里面的方法
factory-bean属性:用于指定实例工厂的bean的id
factory-method属性:用于指定实例工厂中创建对象的方法
6、spring的依赖注入
它是spring框架核心IOC的具体实现方式。简单说,就是坐等框架把对象传入,而不用我们自己获取
-
构造函数注入
顾名思义,就是使用类的构造函数,给成员变量赋值
要求:类中需要提供一个对应参数列表的构造函数
涉及的标签:
constructor-arg
属性:
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称
value:它能赋的值是基本数据类型和string类型
ref:它能赋的值是其它bean类型,也就是必须在配置文件中配置过的bean -
set方法注入
顾名思义,就是在类中提供需要注入成员的set方法
通过配置文件给bean中的属性传值:使用set方法的方式
涉及的标签:property
属性:
name:找的是类中set方法的后面部分
value:给属性赋值是基本数据类型和string类型的
ref:给属性赋值是其它bean类型的,也就是必须在配置文件中配置过的bean -
使用p名称空间注入数据(本质还是调用set方法)
此方法是通过在XML中导入p名称空间,使用p:propertyName来注入数据,它的本质仍然是调用类中的set方法实现注入功能。