1. ⼯⼚设计模式
概念:通过⼯⼚类,创建对象
好处:解耦合
耦合
指的是代码间的强关联关系,⼀⽅的 改变会影响到另⼀⽅
问题:不利于代码维护
简单:把接⼝的实现类,硬编码在程序中
UserService userService = new UserServiceImpl();
UserServiceImpl 可能会改变,不符合开闭原则(打开扩展,关闭修改)
总结
Spring本质:⼯⼚ ApplicationContext (applicationContext.xml)
2. 核心 API
ApplicationContext
-
作⽤:Spring提供的 ApplicationContext这个⼯⼚,⽤于对象 的创建
-
好处:解耦合
ApplicationContext接⼝类型
接⼝:屏蔽实现的差异
-
⾮web环境 :
ClassPathXmlApplicationContext (main junit)
-
web环境 :
XmlWebApplicationContext
是重量级资源
ApplicationContext⼯⼚的对象占⽤⼤量内存。
不会频繁的创建对象 : ⼀个应⽤只会创建⼀个⼯⼚对象。
ApplicationContext⼯⼚:⼀定是线程安全的(多线程并发访问)
Spring ⼯⼚创建的对象,叫做bean或者组件(componet)
细节
Spring ⼯⼚是可以调⽤对象私有的构造⽅法创建对象
name 属性:别名
作⽤:⽤于在Spring的配置⽂件中,为 bean对象定义别名(⼩名)
区别:别名可以定义多个,但是id属性只能有⼀个值
问题:未来在开发过程中,是不是所有的对象, 都会交给Spring⼯⼚来创建呢?
理论上是的,但是有特例 :实体对象(entity)是不会交给Spring创建,它是由持久层框架进⾏创建。
3. Spring5.x与⽇志框架的整合
Spring 与⽇志框架进⾏整合,⽇志框架就可以在控制台中,输出 Spring 框架运⾏过程中的⼀些重要的信息。
好处:便于了解Spring框架的运⾏过程,利于程序的调试
Spring5.x 默认整合的⽇志框架:logback log4j2
4. 注⼊(Injection)
为什么要注入
通过Spring⼯⼚及配置⽂件,为所创建对象的成员变量赋值
通过编码的⽅式,为成员变量进⾏赋值,存在耦合
public void test7() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person");
person.setId(1);
person.setName("suns");
System.out.println("person = " + person);
}
如何进⾏注⼊
类的成员变量提供set get⽅法
配置spring的配置⽂件
Set 注入
构造注入
注⼊:通过Spring的配置⽂件,为成员变量赋值
Set注⼊:Spring调⽤Set⽅法 通过配置⽂件为成员变量赋值
构造注⼊:Spring调⽤构造⽅法 通过配置⽂件 为成员变量赋值
7. 反转控制 与 依赖注⼊
反转控制(IOC Inverse of Control)
控制:对于成员变量赋值的控制权
反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到 Spring ⼯⼚和配置⽂件中完成
好处:解耦合
底层实现:⼯⼚设计模式
依赖注⼊ (Dependency Injection DI)
注⼊:通过Spring的⼯⼚及配置⽂件,为对象(bean,组件)的成员变量赋值
依赖注⼊:当⼀个类需要另⼀个类时,就意味着 依赖,⼀旦出现依赖,就可以把另⼀个类作为本类的成员变量,最终通过Spring配置⽂件进⾏注⼊(赋值)。
好处:解耦合
8. Spring⼯⼚创建复杂对象
复杂对象:指的就是不能直接通过new构造⽅法
创建的对象 Connection SqlSessionFactory
Spring⼯⼚创建复杂对象的3种⽅式
FactoryBean接⼝
实现FactoryBean接⼝
9. 对象的生命周期
什么是对象的⽣命周期
指的是⼀个对象创建、存活、消亡的⼀个完整过程
为什么要学习对象的⽣命周期
由Spring负责对象的创建、存活、销毁,了解⽣命周期,有利于我们使⽤好Spring为我们创建的对象
⽣命周期的3个阶段
1. 创建阶段
Spring⼯⼚何时创建对象
-
scope="singleton"
这种情况下 也需要在获取对象的同时,创建对象
<bean lazy-init="true"/>
-
scope="prototype"
Spring⼯⼚会在获取对象的同时,创建对 象 ctx.getBean("")
2. 初始化阶段
资源的初始化:数据库 IO ⽹络
Spring⼯⼚在创建完对象后,调⽤对象的初始化⽅法,完成对应的初始化操作
初始化⽅法的提供:程序员根据需求,提供初始化⽅法,最终完成初始化操作
初始化⽅法的调⽤:Spring⼯⼚进⾏调⽤
实现初始化的两种方式
-
实现 InitializingBean 接口
/** * 这个就是初始化方法:做一些初始化操作 * Spring会进行调用 * * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { System.out.println("Product.afterPropertiesSet"); }
-
对象中提供⼀个普通的⽅法
public void myInit() { System.out.println("Product.myInit"); }
并在配置文件指定
<bean id="product" scope="prototype" class="cn.duniqb.life.Product" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="suns"/> </bean>
3. 销毁阶段
主要指的就是资源的释放操作
Spring销毁对象前,会调⽤对象的销毁⽅法,完成销毁操作
Spring什么时候销毁所创建的对象?
- ctx.close();
销毁⽅法:程序员根据⾃⼰的需求,定义销毁⽅法,完成销毁操作
调⽤:Spring⼯⼚完成调⽤
实现销毁两种方式
-
实现 DisposableBean 接口
/** * 销毁方法:销毁操作(资源释放的操作 ) * * @throws Exception */ @Override public void destroy() throws Exception { System.out.println("Product.destroy"); }
-
定义⼀个普通的销毁⽅法
public void myDestroy() throws Exception { System.out.println("Product.myDestroy"); }
并在配置文件指定
<bean id="product" scope="prototype" class="cn.duniqb.life.Product" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="suns"/> </bean>
细节分析
销毁⽅法的操作只适⽤于 scope="singleton"
13. 后置处理 Bean:BeanPostProcessor,是一个接口
对Spring⼯⼚所创建的对象,进⾏再加⼯。
实现BeanPostProcessor规定接⼝中的⽅法:
Object postProcessBeforeInitiallization(Object bean String beanName)
作⽤:Spring创建完对象,并进⾏注⼊后,可以运⾏Before⽅法进⾏加⼯获得Spring创建好的对象 :通过⽅法的参数最终通过返回值交给Spring框架
Object postProcessAfterInitiallization(Object bean String beanName)
作⽤:Spring执⾏完对象的初始化操作后,可以运⾏After⽅法进⾏加⼯获得Spring创建好的对象 :通过⽅法的参数最终通过返回值交给Spring框架