Spring框架的设计理念
Spring框架的设计理念
Spring的骨骼架构
Spring的核心组件只有三个:Core、Context和Bean,而AOP、Web这样的上层特性功能都是在这三个的基础上构建的
设计理念
三个核心组件中的核心是Bean组件,Spring可以给视为面向Bean编程
Bean对于Spring的作用就是Object对OOP的意义一样,Spring解决的一个非常关的问题就是,可以让你把对象之间的依赖关系转而用配置文件来管理,也就是依赖注入机制,而Ioc容器中存在的,就是被Bean包裹的对象
核心组件如何协调工作
Bean包装的是Object,而Object必然有数据,如何给这些数据提供生存环境就是Context要解决的问题,对于Context来说就是要发现每个Bean之间的关系,然后为它们建立这种关系并进行维护,所以Context就是一个Bean关系的集合
而Core就是发现、建立和维护每个Bean之间的关系所需要的一系列工具,Core更像是一个Util
核心组件详解
Bean组件
Bean组件在Spring的org.springframework.beans包下,这个包下所有的类主要解决了三个问题:Bean的定义、Bean的创建以及对Bean的解析,对于使用者来说只需关系Bean的创建
Bean的创建时典型的工厂模式,顶级接口时BeanFactory,其有三个子类:ListableBeanFactory、HierarchiaclBeanFactory和AutowireCapableBeanFactory,但其实最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口。定义这么多层次的接口是为了适配各种使用的场景,区分在Spring内部对象的传递和转化的过程中对对象数据访问所做的限制。例如ListableBeanFactory接口表示这些Bean是可列表的,HierarchiaclBeanFactory表示这些类是有继承关系的,也就是每个Bean可能有父Bean,AutowireCapableBeanFactory接口定义Bean的自动装配规则
Bean的定义主要由BeanDefinition描述,完整地描述了在Spring的配置文件中你定义的
而Bean的解析过程很复杂,功能划分很细,被拓展的地方很多,保证有足够的灵活性。Bean的解析主要就是对Spring的配置文件的解析
Context组件
Context在org.springframework.context包下,实际上就是给Spring提供一个运行时的环境,以保存各个对象的状态
ApplicationContex是context的顶级父类,除了能标识一个应用环境的而基本信息外,还继承了5个接口,拓展context的功能
ApplicationContex继承了BeanFactory,这点说明了Spring容器中运行的主体对象是Bean。另外,ApplicationContext继承了ResourceLoader接口,使得其可以访问到任何外部资源
ApplicationContex的子类主要包含两个方面:
- configurableApplicationContext表示该Context是可以修改的,也就是在构建Context中,用户可以动态添加或者修改已有的配置信息
- WebApplication是为Web准备的Context,可以直接访问ServletContext
总的来说,ApplicaitonContext必须要完成以下几件事情:
- 标识一个应用环境
- 利用BwanFactory创建Bean对象
- 保存对象关系表
- 能够捕获各种事件
context作为Spring的Ioc容器,基本上整合了Spring的大部分功能
Core组件
其一个重要的组成部分就是定义了资源的访问方式,将所有的资源抽象成一个接口
Resource接口封装了各种可能的资源类型,也就是对使用者来说屏蔽了文件类型的不同
Resource接口继承了InputSreamSource接口,在接口中有个getInputSream方法,返回InputStream类,这样屏蔽了资源的提供者
资源的加载任务是由ResourceLoader接口完成的,它屏蔽了所有的资源加载者的差异,只要实现这个接口就可以加载所有的资源,默认实现为DefultResourceLoader
Ioc容器的工作
创建BeanFatory工厂
Ioc容器实际上是Context组件结合其他两个组件共同构建了一个Bean关系网,如果就在AbstractApplicationContext类的refresh方法中,主要包含以下几个步骤:
- 构建BeanFactory
- 注册可能感兴趣的事件
- 创建Bean实例对象
- 触发被监听的事件
创建Bean实例并构建Bean的关系网
- 从finishBeanFactoryInitialization方法开始
- Bean的实例化实在BeanFactory中发生的
- 一个非常重要的Bean:FactoryBean,Spring中一大半的拓展功能都与这个Bean有关,这是一个特殊的Bean。其是一个工厂Bean,可以产生Bean实例的Bean,通过继承FactoryBean并实现它的getObject方法即可自定义产生实例对象的方法
Ioc容器的扩展点
- BeanFactoryPostProcessor:构建BeanFactory时被调用
- BeanPostProcessor:构建Bean对象时被调用
- InitializingBean:创建Bean实例时被调用
- DisPosableBean:销毁Bwan实例时被调用
以上四点就是常见通过实现在这些接口中定义方法来拓展Ioc使得Spring完成我们自定义的任务
AOP
动态代理的实现原理
JDK的java.lang.reflect包下面有一个Proxy类,这个就是构造代理类的入口,这个类有个方法为newProxyInstance,这个就是创建代理对象的地方。此方法需要三个参数:
- ClassLoader:用于加载代理类的Loader类,通常和被代理的类时同一个类
- Interfaces:要被代理的接口
- InvocationHandler:用于执行除了被代理接口中方法之外的用户自定义的操作,也是用户需要代理的最终目的。用户调用目标方法都被代理到在InvocationHandler类中定义的唯一方法invoke()中
Spring AOP如何实现
代理的目的时调用目标方法时可以转而执行InvocationHandler类的invoke方法,因此Spring实现AOP的关键就是在Invocation上做文章
Spring引用了Aop Allicance定义的接口。要实现代理类,在Spring的配置文件定义Bean的时候要设置被代理的接口和接口的实现类(目标类),以及拦截器
从代理类上来看,其继承了FactoryBean的ProxyFactory,也就是之前提到的Spring自身的拓展点
在Spring创建了代理对象后,当调用目标对象上的方法时,都会被代理到InvocationHandler类的invoke方法中执行