一、Spring的设计理念概述
Spring核心:Spring三大组件为Context、Bean、Core,核心为Bean,Bean对于Spring就相当于对象对于面向对象,其重要性可想而知。
Spring流行原因:解决了一个非常关键的问题,通过Spring,可以把对象之间的依赖交由配置文件管理,也就是依赖注入机制(DI)。在Spring中,这些依赖的具体应用是由IOC容器控制管理的,IOC容器中存放的是Bean,Bean中存放的是对象。IOC就是通过把对象包装在Bean中达到对这些对象管理以及一系列额外操作的目的。
Spring设计策略:构建一个数据结构(Bean),然后根据这个数据结构设计它的生存环境(Context+Core),并让它在这个环境中按照一定规律运动,并在运动过程中与其他个体完成信息交换完成功能。
二、Spring核心组件(Bean、Context、Core)
Bean:包装Object,保存数据。相关概念:
Bean实例:用户所需的实例对象;
Bean:生产Bean实例的模板,实例化后会产生Bean实例(类似于类与对象的关系);
BeanFactory:生产Bean的工厂。
FactoryBean:可以生产Bean实例的工厂Bean,可以通过getObject()方法直接获取Bean实例;(与Bean区别在于:FactoryBean可自行生产Bean实例,而Bean不行。)
Context:也就是IOC容器,提供了创建并维持
Bean以及Bean之间关系的环境支撑。所以说Context是一个Bean的关系集合。
Core:也就是完成Context工作所需的工具,可以理解为Util。
Context作为中间件,结合Bean核心、Core工具构建了一个Bean关系网。
三、Spring核心组件详解
1、Bean——org.springframework.beans包,Bean定义、Bean创建、Bean解析
Bean定义由BeanDefinition描述。在Spring成功解析了你在配置文件中配置的<bean/>或注解的bean时,就将每个Bean转化为一个BeanDefinition,是后续操作的基础。
Bean创建使用的是工厂模式,顶级接口为BeanFactory(代表着一种基本的IOC容器),然后由三个子接口用于定义不同类型Bean的生产过程(可列表的、有继承的、自动装配的)。默认实现类为DefaultListableBeanFactory。
2、Context——org.springframework.context包
ApplicationContext是Context的顶级父类(代表着扩展了的IOC容器),实现了BeanFactory接口,证明Spring容器中运行主体为Bean;实现了ResourceLoader接口,使Application可以访问任意外部资源;实现了一些其他接口,如:MessageSource,可以进行国际化消息处理。
Application必须完成以下几件事,也是Context、IOC容器必须完成的几件事:
1、标识一个应用环境;
2、利用BeanFactory创建Bean;
3、保存对象关系表;
4、能够捕获各种事件。
这里有一点需要注意,而且是面试常问的一点:BeanFactory与ApplicationContext区别?
简单来说,BeanFactory是只支持依赖注入的基本版本IOC,而ApplicationContext是扩展版本的IOC。
(1)BeanFactory
XmlBeanFactory bFactory = new XmlBeanFactory(new ClassPathResource("Spring.xml"));
获取某个类的实例时如下:
BeansDemoClass beans = (BeansDemoClass) bFactory.getBean("beansDemoClass");
(2)ApplicationContext
ApplicationContext aContext = new ClassPathXmlApplicationContext("Spring.xml"); BeansDemoClass bDemoClass = (BeansDemoClass)aContext.getBean("beansDemoClass");
二者对Bean的初始化也有很大区别。BeanFactory当需要调用时读取配置信息,生成某个类的实例。如果读入的Bean配置正确,则其他的配置中有错误也不会影响程序的运行。而ApplicationContext 在初始化时就把 xml 的配置信息读入内存,对 XML 文件进行检验,如果配置文件没有错误,就创建所有的Bean ,直接为应用程序服务。相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
3、Core——org.springframeword.core包,提供了IOC容器完成功能的工具基础。
比如定义了资源的访问方式,把所有的资源类型都抽象为一个接口——Resource接口;它继承了InputStreamResource接口,可以通过其中的getInputStream()方法将所有类型资源都转换成InputStream实例,屏蔽了差异,使操作统一。
四、Spring IOC如何工作
构建IOC容器的核心方法:AbstractApplicationContext中的fresh方法。
如何使用IOC?
1、准备配置文件:applicationContext.xml(也可以起其他的名字),在配置文件中定义Bean也就是为Bean配置元数据(元数据由class属性配置)。其中,
Spring配置定义Bean主要有三种方式:
1、通过无参构造器方式,最简单的一种方式。
2、通过静态工厂的方式,定义一个静态的工厂方法。
3、通过实例化工厂方式,配置比较繁琐。
依赖注入主要有四种方式:
1、setter注入
2、构造方法注入
3、接口注入
4、推荐使用的,注解注入
(详情可参看:http://blog.csdn.net/zljjava/article/details/7530669,http://outofmemory.cn/code-snippet/3670/spring-inject-by-annotation)
2、由IOC容器进行解析元数据: IOC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IOC容器根据BeanDefinition进行实例化、配置及组装Bean。
3、实例化IOC容器:由客户端实例化容器,获取需要的Bean实例。其中实例化IOC容器主要有两种方式:
1、从classpath获取配置文件:
ApplicationContext app = new ClassPathXmlApplicationContext("classpath.xml");
2、从文件系统中获取配置文件:
ApplicationContext app = new FileSystemXmlApplicationContext("fileSystemConfig.xml");
如何扩展IOC?
(1)FactoryBean,用户可以通过实现FactoryBean接口、实现getObject()方法的方式,自定义生产Bean实例。这种方式也是用户最常见的扩展 方式,可参看实例:http://haohaoxuexi.iteye.com/blog/2074583
(2)BeanFactoryPostProcessor,在创建BeanFactory时调用,用户可以实现它做一些自定义的操作。
(3)BeanPostProcessor,在创建Bean时调用。
(4)InitializingBean、DisposableBean,Bean实例创建时和销毁时调用。