spring 是面向Bean的编程
Ioc (Inversion of Control) 控制反转/依赖注入(DI:Dependency Injection)
Aop(Aspect Oriented Programming) 面向切面编程
spring框架概述
Bean的作用域
默认情况下为单例模式:scope="singleton"
<bean id ="user" class="entity.User"/>
<bean is = "user" class= "entity.User" scope="singleton"/>
类别 | 说明 |
---|---|
singleton(单例) | 在spring容器中仅存在一个共享的Bean实例 |
prototype(原型) | 每次从容器中都是获取一个新的实例 |
request | 每次请求都会创建一个新的Bean实例 |
session | 同一个HTTP请求共享一个Bean实例 |
global Session | 同一个全局Session共享一个Bean实例 |
注:request,session, global session模式,仅适用于WebApplicationContext环境
spring Bean封装机制
Spring 以Bean的方式管理所有的组件,java EE 的全部组件都是被视为Bean管理
Bean 在Spring 的容器中运行,Spring负责创建Bean的实例,并管理其生命同期
BeanFactory
由org.springframework.beans.factory.BeanFactory接口定义
BeanFactory 是工厂模式(Factory pattern)的实现,负责创建和管理bean
ApplicationContext 是BeanFactory的子接口
实现类 ClassPathXmlApplicationContext(用于查找根目录下的配置文件)
实现类 FileSystemXmlApplicationContext(用于查找系统盘下的配置文件)
当我们有多个配置文件时
ApplicationContext context = new ClassPathXmlApplication(new String[]{
"conf/bean1.xml", "conf/bean2.xml"
})
控制反转/依赖注入
将组件对象的控制权从代码本身转移到外部容器
组件化的思想:分离关注点,接口与实现分离
依赖的注入:将组件的构建和使用分开
Ioc使用两大关键技术一个设计模式
JDOM: 用于解析配置文件
反射机制
工厂模式(单例模式)
spring Ioc原理解析
导入所需要的所需要的jar包
创建接口ITestDao
分别创建两个实现类TestDao 和NewDao
创建业务类TestBiz,当我们需要调用ITestDao时,必须new一个实例
耦合
当直接new 一个实例时,代码就高度耦合,那么怎么解耦合呢,这里引入工厂模式,我们创建一个工厂类,把new 实例的权利交给工厂,我们直接和工厂要就行
业务层通过工厂得到一个ITestDao的实例
这样数据层和业务层就实现了解耦合
那么spring是怎么实现解耦合的呢,接下来我们接着修改
修改业务层,使之面向接口的实现
创建接口ITestBiz
修改TestBiz类
实现ITestBiz接口
声明dao层接口的属性,并提供getter/setter方法
编写spring的配置文件,applicationContext.xml
导入schema文件
在spring配置文件里声明需要spring管理的Bean,就是创建一个对象
创建测试类TestIoc
如果我们现在通过new TestBiz类,会得到什么?
运行main方法
报错空指针异常
那么,应该怎么做呢?当我们把bean交给spring容器管理后,我们应该向spring索要需要的bean
首先,把配置文件applicationContext.xml读取进来
通过 getBean()方法得到所需要的实例,传入配置文件声明的bean的id
运行main方法
实现过程,通过getBean()传入的参数testBiz找到 -----> 配置文件中的id为testBiz的bean组件-----》实例化对象(new TestBiz())---->在TestBiz类中有一个dao的属性------>调用setData()方法给dao属性初始化(testBiz.setDao(testDao))----->通过引用的testDao找到id为testDao的bean ---->实例化一个TestDao对象(new TestDao())
当我们需求变更时,我们直接在配置文件中替换组件就行,例如我们想要NewDao的实例
直接运行main方法,看看输出了什么?
输出了NewDao中的数据
总结:spring 扮演了一个工厂的角色,所有的类都是一个组件,一个bean
默认情况下spring 只会创建一个对象,所有的调用者共享一个实例,我们来验证一下
我们来再一次调用getBean()方法,赋值给新的变量,我们来判断两个变量的内存地址是否相等
结果为true ,我们在配置文件中把bean 的作用域修改为prototype
接着我们来再次运行
结果为false
spring 在启动时会把所有的作用域为单例的bean都进行实例化
这时我们看到testDao在spring初始化之前就实例化,而testBiz是spring初始化后实例化的。当我们把配置文件中的作用域修改成单例模式后
运行程序查看结果
testBiz在spring初始化之前完成了实例化
来自为知笔记(Wiz)