- 浏览: 430126 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (145)
- spring (14)
- struts (3)
- hibernate (3)
- ibatis (6)
- web容器 (3)
- java (51)
- 哈希 (1)
- 认证 (1)
- 设计模式 (2)
- 部署_系统 (9)
- hadoop (5)
- shell (5)
- python (2)
- 数据库 (6)
- javascript (3)
- ajax (1)
- servlet (1)
- web前端 (5)
- linux (3)
- ubuntu (5)
- svn (3)
- 报错积累 (1)
- REST (1)
- maven (1)
- josso (2)
- interview (0)
- 其他 (6)
- find . -type f -mmin -10 //10分钟内修改过的 (0)
最新评论
-
cuqing:
下说法有误!如果两个对象的hashCode值相同,我们应该认为 ...
为什么在重写了equals()方法之后也必须重写hashCode()方法 -
Tough小白:
11111111 11111111 11111111 1111 ...
为什么byte取值是-128到127 -
世界尽头没有你:
Cloudera Hadoop5&Hadoop高阶管理 ...
hadoop版本及cloudera的CDH3 CDH4 -
00915132:
感谢楼主~~~~长知识了
java Process的waitFor() -
david8866:
非常感谢楼主的分享,解决了我的问题
java Process的waitFor()
转自 http://www.iteye.com/magazines/72
本文主要以 spring ioc 容器基本代码骨架为切入点,理解 ioc 容器的基本代码组件结构,各代码组件细节剖析将放在后面的学习文章里。
关于IOC容器
IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等。
先从我们自己设计这样一个视角来考虑:
所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。
对象和对象关系怎么表示?
可以用 xml , properties 文件等语义化配置文件表示。
描述对象关系的文件存放在哪里?
可能是 classpath , filesystem ,或者是 URL 网络资源, servletContext 等。
回到正题,有了配置文件,还需要对配置文件解析。
不同的配置文件对对象的描述不一样,如标准的,自定义声明式的,如何统一? 在内部需要有一个统一的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。
如何对不同的配置文件进行解析?需要对不同的配置文件语法,采用不同的解析器。
基于以上问题,对应过来,刚好是 spring ioc 容器抽象的的几个主要接口:
Resource
BeanDefinition
BeanDefinitionReader
BeanFactory
ApplicationContext
以上五个都是接口,都有各式各样的实现,正是这 5 个接口定义了 spring ioc 容器的基本代码组件结构。而其组件各种实现的组合关系组成了一个运行时的具体容器。
各代码组件详解
1.Resource
是对资源的抽象,每一个接口实现类都代表了一种资源类型,如 ClasspathResource 、 URLResource , FileSystemResource 等。每一个资源类型都封装了对某一种特定资源的访问策略。它是 spring 资源访问策略的一个基础实现,应用在很多场景。
具体可以参考文章 :
Spring 资源访问剖析和策略模式应用
http://www.ibm.com/developerworks/cn/java/j-lo-spring-resource/index.html
2.BeanDefinition
用来抽象和描述一个具体 bean 对象。是描述一个 bean 对象的基本数据结构。
3.BeanDefinitionReader
BeanDefinitionReader 将外部资源对象描述的 bean 定义统一转化为统一的内部数据结构 BeanDefinition 。对应不同的描述需要有不同的 Reader 。如 XmlBeanDefinitionReader 用来读取 xml 描述配置的 bean 对象。
4.BeanFactory
用来定义一个很纯粹的 bean 容器。它是一个 bean 容器的必备结构。同时和外部应用环境等隔离。 BeanDefinition 是它的基本数据结构。它维护一个 BeanDefinitions Map, 并可根据 BeanDefinition 的描述进行 bean 的创建和管理。
5.ApplicationContext
从名字来看叫应用上下文,是和应用环境息息相关的。没错这个就是我们平时开发中经常直接使用打交道的一个类,应用上下文,或者也叫做 spring 容器。其实它的基本实现是会持有一个 BeanFactory 对象,并基于此提供一些包装和功能扩展。为什么要这么做呢?因为 BeanFactory 实现了一个容器基本结构和功能,但是与外部环境隔离。那么读取配置文件,并将配置文件解析成 BeanDefinition ,然后注册到 BeanFactory 的这一个过程的封装自然就需要 ApplicationContext 。 ApplicationContext 和应用环境细细相关,常见实现有 ClasspathXmlApplicationContext,FileSystemXmlApplicationContext,WebApplicationContext 等。 Classpath 、 xml 、 FileSystem 、 Web 等词都代表了应用和环境相关的一些意思,从字面上不难理解各自代表的含义。
当然 ApplicationContext 和 BeanFactory 的区别远不止于此,有:
1. 资源访问功能:在 Resource 和 ResourceLoader 的基础上可以灵活的访问不同的资源。
2. 支持不同的信息源。
3. 支持应用事件:继承了接口 ApplicationEventPublisher ,这样在上下文中为 bean 之间提供了事件机制。
……
以上 5 个组件基本代表了 ioc 容器的一个最基本组成,而组件的组合是放在 ApplicationContext 的实现这一层来完成。
以ClasspathXmlApplicationContext 容器实现为例,其组合关系如下:
ClassPathXmlApplicationContext的refresh() 方法负责完成了整个容器的初始化。
为什么叫refresh?也就是说其实是刷新的 意思,该IOC容器里面维护了一个单例的BeanFactory,如果bean的配置有修改,也可以直接调用refresh方法,它将销毁之前的 BeanFactory,重新创建一个BeanFactory。所以叫refresh也是能理解的。
以下是Refresh的基本步骤:
1.把配置xml文件转换成resource。resource的转换是先通过ResourcePatternResolver来解析可识别格式的配置文件的路径
(如"classpath*:"等),如果没有指定格式,默认会按照类路径的资源来处理。
2.利用XmlBeanDefinitionReader完成对xml的解析,将xml Resource里定义的bean对象转换成统一的BeanDefinition。
3.将BeanDefinition注册到BeanFactory,完成对BeanFactory的初始化。BeanFactory里将会维护一个BeanDefinition的Map。
当getBean的时候就会根据调用BeanFactory,根据bean的BeanDifinition来实例化一个bean。当然根据bean的lazy-init、protetype等属性设置不同以上过程略有差别。
refresh()代码如下:
- public void refresh() throws BeansException, IllegalStateException {
- synchronized ( this .startupShutdownMonitor) {
- // Prepare this context for refreshing.
- prepareRefresh();
- // Tell the subclass to refresh the internal bean factory.
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- // Prepare the bean factory for use in this context.
- prepareBeanFactory(beanFactory);
- try {
- // Allows post-processing of the bean factory in context subclasses.
- postProcessBeanFactory(beanFactory);
- // Invoke factory processors registered as beans in the context.
- invokeBeanFactoryPostProcessors(beanFactory);
- // Register bean processors that intercept bean creation.
- registerBeanPostProcessors(beanFactory);
- // Initialize message source for this context.
- initMessageSource();
- // Initialize event multicaster for this context.
- initApplicationEventMulticaster();
- // Initialize other special beans in specific context subclasses.
- onRefresh();
- // Check for listener beans and register them.
- registerListeners();
- // Instantiate all remaining (non-lazy-init) singletons.
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- finishRefresh();
- }
- catch (BeansException ex) {
- // Destroy already created singletons to avoid dangling resources.
- beanFactory.destroySingletons();
- // Reset 'active' flag.
- cancelRefresh(ex);
- // Propagate exception to caller.
- throw ex;
- }
- }
- }
以上的obtainFreshBeanFactory是很关键的一个方法,里面会调用loadBeanDefinition方法,如下:
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
- // Create a new XmlBeanDefinitionReader for the given BeanFactory.
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
- // Configure the bean definition reader with this context's
- // resource loading environment.
- beanDefinitionReader.setResourceLoader(this );
- beanDefinitionReader.setEntityResolver(new ResourceEntityResolver( this ));
- // Allow a subclass to provide custom initialization of the reader,
- // then proceed with actually loading the bean definitions.
- initBeanDefinitionReader(beanDefinitionReader);
- loadBeanDefinitions(beanDefinitionReader);
- }
LoadBeanDifinition方法很关键,这里特定于整个IOC容器,实例化了一个XmlBeanDefinitionReader来解析Resource文件。关于Resource文件如何初始化和xml文件如何解析都在
- loadBeanDefinitions(beanDefinitionReader);
里面的层层调用完成,这里不在累述。
小结
Spring 的扩展性是毋庸置疑的,学习 spring 的设计是一个很好的实践理论结合。主要个人觉得有几点:
1. 框架顶层的设计有着很好的抽象,遵循面向接口编程的规范。 Resource 、 BeanFactory 、 ApplicationContext 都是非常好的接口抽象,非常明确的定义了该组件的一些功能。
2. 利用组合模式。
3. 个组件的实现里大量使用了模板方法模式,提升了同一组件代码的复用性。
4. 各种设计保留了扩展的接口,很多基于 spring 的框架都可以很容易的介入实现了自己的一些扩展。
5. 框架里采用里很多经典的设计模式,如代理、装饰、策略等等。
发表评论
-
springmvc处理异常的4种方式
2015-03-03 16:20 799http://zxy-920823.iteye.com/blo ... -
spring定义的5个事务隔离级别和7种传播行为
2013-07-09 14:15 6322在TransactionDefinition接口 ... -
spring mvc controller 异常处理
2013-05-15 15:10 8194Spring3.0中对异常的处理方法一共提供了两种: 一 ... -
spring事务配置
2013-05-15 15:08 974第一种配置方法:基于XML的事务管理 这种方法不需要对原有 ... -
spring的FactoryBean 和Beanfactory
2012-03-27 18:12 1159转自http://fluagen.blog.51cto. ... -
对Spring IoC容器实现的结构分析
2012-03-12 11:04 1221转自http://www.iteye.com/topic/11 ... -
spring+struts2+ibatis
2012-03-03 15:18 1038* Struts2依赖包//struts2.2.3最小j ... -
spring2.5注释
2011-08-11 14:13 953注解说明 • 注册注解处理器 • 方式一:bean ... -
AOP面向切面编程
2011-03-25 23:02 1061利用AOP可以对业务逻辑的各个部分进行隔离,降低业务逻辑之间的 ... -
spring的BeanFactory和AplicationContext
2011-03-25 19:50 3537org.springframework.aop — ... -
spring设计模式的理解
2011-03-21 13:03 969spring设计模式的理解 -
svn
2011-01-13 11:36 1048一、安装svn: 1、从svn ... -
Ant
2010-11-01 10:12 930当一个代码项目大 ...
相关推荐
spring IOC学习源码
Spring IoC 入门实例,包括了多种依赖注入方式,适合Spring初学者学习使用。实例里有详细的注释,一看就懂。
老王读 Spring IoC 系列文章的源码分析&测试代码 Spring IoC 源码分析,帮助大家学习 Spring 源码,更加了解 Spring 的底层 博客专栏地址:https://blog.csdn.net/wang489687009/category_11269905.html
个人学习spring框架时记录的笔记,纯手敲,SpringIOC+SpringMVC学习笔记,有兴趣的可以参考
学习Spring过程中,使用Eclipse调试Spring源码的关键断点文件。
springIOC 小例子 附带源码 适合新手学习
这是我手写的 spring ioc 源码,第一版初步完成,支持构造器推断选择,支持属性的循环依赖,支持注解功能,与spring源码相似度非常高,对spring源码不了解但又想学习的,强烈建议看这个,后续继续更新
spring net IOC+AOP 源码 刘冬老师博客学习
1、spring 的整体架构 2、spring的基本实现(xml的加载原理、标签解析、bean加载) 3、容器扩展 4、ioc和aop 5、事务 6、springmvc 7、dispatcherServlet
SpringFramework5.0.x源码学习笔记.pdf,这是一份SpringFramework5.0.x的源码学习笔记,主要通过debug方式学习Spring的核心技术ioc和aop的实现原理
spring学习资料集合,源码+文档 注释详细 完全超值。 jdk代理,springAOP,IOC,注入全部 分工程详细介绍,这是我个人总结的想了好久决定拿出来跟大家分享,希望更多的人能够掌握它,谢谢
本课程通过UML结合源码进行全局的剖析了Spring_IOC容器的核心原理,以及插件的开发方法,以及插件实例(介绍SpingBoot和Spring定时器扩展原理)。通过本课程的学习您将对Spring_IOC整体架构有清晰的了解,知道5大核心...
1、通过分析 Spring 源码,深刻掌握核心原理和设计思想 2、通过本课的学习,完全掌握 SpringIOC 容器的初始化细节,并手绘时序图 3、掌握看源码不
Spring源代码解析(二):ioc容器在Web容器中的启动.doc Spring源代码分析(三):Spring JDBC.doc Spring源代码解析(四):Spring MVC.doc Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):...
com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...
spring ioc, spring aop 源码注释,源码解析,有需要学习spring源码的可以看看,里面有详细的方法注释,以及解析
使用非常频繁,实际上对于源码一直没有静下心来学习过。 但是 spring 源码存在一个问题,那就是过于抽象,导致学习起来成本上升。 所以本项目由渐入深,只实现 spring 的核心功能,便于自己和他人学习 spring 的核心...
BeanFactory是用于访问Spring Bean容器的根接口,是一个单纯的Bean工厂,也就是常说的IOC容器的顶层定义,各种IOC容器是在其基础上为了满
Spring AOP多种代理机制相关核心类介绍先介绍一些Spring Aop中一些核心类,大致分为三类: advisorCreator ,从spring ioc的扩展接口beanPostProcessor继承,主要用作扫描获取advisor。 advisor :顾问的意思,封装...
spring 一、配置阶段 1、web.xml DispatcherServlet 由Spring提供的 2、init-param classpath:application.xml contextConfigLoation 3、url-pattern /* 二、初始化、启动阶段 1、init 加载spring的配置文件 2、IOC...