- 浏览: 83221 次
- 性别:
- 来自: 大连
文章分类
- 全部博客 (49)
- 对象持久化 (1)
- Core Java (7)
- 关系数据库 (0)
- 架构设计 (4)
- Linux&Unix (9)
- 软件思想随想 (4)
- Spring (12)
- Python (0)
- OSGI (0)
- Java Tools (0)
- Java应用服务器 (0)
- MQ (0)
- SOA (0)
- 云计算 (1)
- .Net-C# (2)
- .Net-WCF (0)
- .Net-WPF (0)
- .Net-WF (0)
- .Net Web (0)
- .Net应用服务器 (1)
- Java Web (0)
- 非关系性数据库 (2)
- 生活随想 (3)
- 我的开源社区 (1)
- 管理思想 (0)
- 测试方法论 (0)
- 开发方法论 (2)
- Hadoop (0)
- 工作流 (0)
- Quartz (0)
- ASP.Net MVC (0)
- LinQ (0)
- .Net Platform (2)
- 我的书 (1)
最新评论
-
magicyang919:
很期待,加油做啊。讲清楚how,和why,更重要的是why,重 ...
原来有关Spring核心部分的源代码分析 -
magicyang919:
这个必须顶,我们要知道的就是为什么spring这么设计,而不是 ...
Spring框架核心源代码的分析及其感受-1 -
pastore123:
分析的很好,思维过程讲的很好,通俗易懂
Spring框架核心源代码的分析及其感受-1 -
gbllty1981:
一个简单的基于约定优于配置(Coc)的对象工厂实现 -
沙舟狼客:
其实在开发中有好多都是固定模式的,所以应该用约定;这样维护起来 ...
约定优于配置的一个思考
(事先用Word写好的,再贴上来,格式有点...,有时间再调整,如果看不清楚,请直接下载我写的Word文档,在-6第六篇文章中,有错别字就别怪我了,没有时间检查)
对于 Java 开发者来说,经常会用到一个框架 —Spring, 但是从用的角度来讲,很多人已经认为比较“复杂”了,但是我认为这个和思维方式有关,当人看到一个电视机,然后看完说明书(相当于 Spring 的用户文档),最后在磕磕碰碰的点击各种按钮后电视机开始工作了,但是他某一天想让电视机能干点说明书描述的东西以外的事情的时候,现在的电视机也就无能为力了,比如他想让电视机能够具备播放 N 种格式的视频,并且可以录制电视节目,他买的电视机并不能满足他的要求,必须换新的了,但是恰好他的这个老电视机的电路板上留出了各种插口,可以帮助用户拓展功能,这个说明书没有写,只有维修人员知道,属于内部秘密,因为他们公司所有的电视都用一个电路板的设计做的,只是板子上有不同的插件罢了,这能减少很多设计成本、制作成本、维护成本、人员成本。那么这个用户根本不知道他的电视机还能增强,结果他又买了一个新的,这个新的电视机结果也是用着同样的电路板只是多了几个插件!对于软件这件东西,其实也是一样, spring 也是一个软件,我们就属于那些使用者,如果我们不知道其中的原理,就没有办法有效地在合适的场景下使用 Spring 的一般特性和高级特性,也不知道如何在面对不同的应用环境中如何拓展好它以便更加好的让它为我们的应用服务。以上是一种观点,估计您能理解,我还有一个补充观点,那就是这些出了名的框架包装了很多设计思想,把这些设计思想分解开,你会发现对你自己设计软件时很有帮助,而且不仅仅如此,更加学会了一种阅读代码的方式、学习其设计思想、建立创新型思维的入口的捷径,反倒比看那些什么 Spring 整合 Hibeernate 、 *** 指南等等而学得彻底,但是这些捷径的前提是,我们必须破除一个观念就是“权威的东西一定很复杂或者深奥”的想法,或者会用就行的观念,或者直接去源代码而不去先去了解其理论模型的含义,这些不好的观念是可以把你带到书呆子或者工具狂的恶意帮手。
从这篇文章开始,我将细细的分析 spring 源代码,我大可以去分析什么 Hibernate 、 Struts 等等这些东西,但是我要说我只是拿 Spring 作为特例来做分析,并不是最终目的,最终目的是为了和大家探讨如下几个问题:
1) 如何做设计前的分析
2) 如何利用好现有的知识系统
3) 如何对待各种设计理念
4) 如果学好和用好工具软件
5) 如何学好技术
等等,而且在此中最大可能性的解释共通理念、技术的重要性,如何能做到触类旁通等等。所以这系列的文章绝对不是一个什么指南,或者就是为了分析源代码而分析的文章。
开始之前,我先要照顾一下初学者,什么是 Spring? ( 你可以直接到官方网站上去查 , 不过这里还是给个定义 , 作为 Spring 的整体概念,这个整体概念将被各种子概念解释,各种子概念将被实际的实现解释 )
Spring 提供对象关系解耦的能力,又能使各个松散耦合的对象关联起来实现一个系统的功能,我这里值的系统也是一个整体观念,具体的可能是一个应用层组件系统,也可能就是一个组件,它并且提供对一个对象本身声明周期的管理。好了,这好像是一个很学究的定义,其实上面这个定义还可以翻译成:把一个系统的关注点分离(对象或其他什么东西的关系解耦),然后再让他们协调起来干一个明确目标的事情 . 这样来讲可能是看起来有些矛盾和抽象了,其实我们可以观察一下周围的物件,比如电视机,电视机每个零件都是独立的,比如电子管,这个电子管没有被组装到这个电视机中之前谁也不知道它的作用,还可能装到一个手表里也说不定,所以它的独立的,高内聚低耦合的,然而在设计师的“设计“下,把这些互相独立的零件组装起来,来干电视机应该干的事情,而这些独立的零件,又是可以替换的,坏了或者升级都要替换掉,所以 Spring 这个框架解释了软件设计中最最朴素的也是最最本质的问题那就是对一个概念的关注点的分离或者分层,然后还要使其结合起来实现一个整体的目标!以上看起来很抽象,那么我们先用一个如何使用 Spring 的简单代码示例来说明问题:
设计一个功能(略)
1) 实现各个独立的类
2 )写配置文件
3 )部署
再看看客户程序如何使用这个功能:
New FileSystemXmlApplicationContext(“C:\beans.xml).getBean();
看到了吧,一个功能(整体概念)被分解了,每一个被装配的对象都是可以通过外部配置文件替换的,但是又是一个整体,对立而统一,你会发现每个对象(类的实例)都是可以独立存在的,也可以被装备到其他的应用中,并且可以脱离整体而进行单独测试,这一切带来的好处都是基于上面那么多论述的理由而来的!如此简单,如此优美。接下来我们来看看 Spring 的核心实现 :IOC 和 AOP.( 切忌不可被名词或者什么概念吓倒,很多名词都是在使用隐喻的办法说明一个抽象的概念,是为了离你近一些,明白一些,比如 IOC, 控制反转,控制是隐喻,反转也是隐喻 )
一, IOC 就是 A 类依赖另外 B 类的时候,不需要 A 管理 B 的生命周期,也就是不用再在 A 中来 new B, 也就是说 A 不必知道 B 是否存在,而只是有个接口引用就可以了,那么谁来管理它们之间的依赖(也就是把 A&B 建立一种实际的关系),那就是 IOC 容器干的事情,你可以把它想象成一个中间者,那么具体实现一个控制反转是靠的什么,一个类能和其他类发生依赖的地方基本上是构造函数参数和属性或者方法参数,所以就有了 DI (依赖注入)的具体实现 IOC 的方式:构造函数注入和属性注入,下面是一个简单的伪代码例子:
A a=new A();//IOC 容器来创建
B b=new B();//IOC 容器来创建
a.bRef=b;//IOC 容器来关联
或者
B b=new B();//IOC 容器来创建
A a=new A(b);//IOC 容器来创建
发现所有的 new 和关联工作都“可以“交给 IOC 容器,那么对于 Spring 的设计目的来说, IOC 容器的实现就是其核心部分之一。下面我们来看看 Spring IOC 容器(容器也是一个隐喻 - 一个容器里面肯定能装东西才叫容器,用来说明作用,其实具体实现很简单,后面有讲)的实现 ( 分析的基础是了解其使用、概念或者具体使用过 ):
//#ToDO 源代码文件夹结构
从上面这个源代码文件夹结构中(幸亏他们的名字起的好),我第一眼就看到了 org.springframework.context 这个子项目( Spring 所有的大的独立部分都是以子项目存在的,这样很好独立维护和升级,这也符合分解和结合的观点) , 因为我们经常使用的容器就是 ApplicationContext, 我们以此为入口点进行分析(最好的习惯就是从你最常用或者大家最常用或者框架、软件的说明书上直接入口使用点开始顺藤摸瓜),我在 Eclipse 中看到了 ApplicationContext 的源代码 ( 注释都被我去掉了,是为了更加清晰 ):
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
由于我们之前总是在使用 Spring, 所以一眼就看出来 getParent 能得到“父“容器, getAutowireCapableBeanFactory 与自动装配有关 . 我们再看看它有哪些实现,我猜测我可以看到一个我们非常熟悉的 ApplicationContext ,然后我就可以按这个最熟悉 ApplicationContext 开始分析其原理了,幸好 Eclipse 提供便捷的工具让你知道一个接口有多少实现!请按 F4!
哈哈,可以看到 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext, 这两个都是我们经常用到的 ApplicationContext 实现,我挑 FileSystemXmlApplicationContext 进行分析,切忌在分析一个东西的实现时没有理论基础没有主线或者就直接看源代码,会非常容易进到代码丛林中的,最终迷失在茫茫的代码中(但是实际代码并不多,只是我们自己把自己搞晕了 , 阅读代码时保持一个方向进行,抓清主干然后分析分支是有效的办法, FileSystemXmlApplicationContext 的实现是 :
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {
public FileSystemXmlApplicationContext() {
}
public FileSystemXmlApplicationContext(ApplicationContext parent) {
super (parent);
}
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
this ( new String[] {configLocation}, true , null );
}
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
this (configLocations, true , null );
}
public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
this (configLocations, true , parent);
}
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
this (configLocations, refresh, null );
}
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super (parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();//其他构造函数都是这个构造函数的实现的,而这个构造函数的核心就是这个refresh方法
}
}
@Override
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith( "/" )) {
path = path.substring(1);
}
return new FileSystemResource(path);//解析文件路径为Resouce
}
}
啊?怎么这么多方法?看清楚了很多都是构造函数和一些重载的方法实现( @Override 注释的), 对于可能在前进路上看到的一大坨代码,不要惊呼,先看看整体这些属性和方法的类别(构造函数,方法等等),先分个类,再找关键的部分,找关键的部分也需要技巧,那就是从调用方找,我们客户程序在使用 ApplicationContext 时,不就是先在构造函数中设置一下 XML 配置文件的位置(这个配置文件就是声明了对象之间依赖关系的地方),然后通过 getBean 方法取的容器中的 Bean( 装配好的 ) 实例吗?所以我主动在上面的代码寻找构造函数的细节和 getBean 方法,等找到这些关键部分之后,我们再看支持它们实现的类变量,属性和其他方法即可,可但是我在上面的代码中没有看到什么 getBean 方法,只看到构造函数中的细节了,而且很多地方用 super 调用父类的构造函数之实现,因为总和 OO 这类的语言打交道,直接会就想到 getBean 可能在父类中!但是稍等一下,从调用方使用它的角度看,构造函数应该是解析 XML 配置的地方,而 XML 配置文件中讲述了如何装配 Bean 的信息,看来 getBean 方法依赖于这个解析过程,这是一个基础!好了!先不要马上进入找 getBean 的过程吧,先把它的基础搞明白,开始找 XML 解析的过程!对!你应该看到了,在
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super (parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
这个构造函数中(其他构造函数都是调用这个构造函数的),貌似看到了一些端倪,第一关联了 parent, 估计 AppliactionContext 父子关系建立是通过这方式的!但是我现在先不关心这个的实现,我是想知道 XML 如何被解析的, setConfigLocation 方法的调用也不是,从名字上猜出八九不离十(你看,写程序的时候,名字越贴切越好,给各位推荐一本书《代码整洁之道》),只能是 refresh 方法了,从上面的代码分析我大概知道 XML 解析就在这里面实现的,但是这个方法干了些其他什么事情我还不知道(分析代码时,必须有点想象力,但是这种想象力必须建立在“证据“上,不要瞎猜),我迫不及待地按 F3 进入 refresh 方法中看个究竟 ( 这时你发现 refresh 方法是在 AbstractApplicationContext 类中实现的 , 为什么在这里实现?除了 OO 继承的观念外,还有一种设计思想在里面,这个思想我在后面的分析中会写到 ) :
public void refresh () throws BeansException, IllegalStateException {
synchronized ( this . startupShutdownMonitor ) {
// Prepare this context for refreshing.
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
...
其实这里是一个初始化ApplicationContext的过程模板(模板设计模式),基类里面的主方法Refresh起到一个流程整合的作用,其调用的方法可能是抽象方法,需要子类去实现的,这样做的好处是,在一固定算法框架下,做到分步实现的解藕,想象一下,每一个分步都是可以被子类替换的,利用模板设计模式把过程也解藕了。
另外,你还可以看到上面有MessageSource,PostProcessor,applicationEvent的内容,熟悉Spring使用的朋友,你应该知道这里是干了什么了,有时间的话,我们就回来分析分析这些方法!不过我们现在先研究一下obtainFreshBeanFactory()
- Spring框架核心源代码的分析及其感受-1.rar (93.8 KB)
- 下载次数: 109
评论
发表评论
-
约定优于配置的一个思考
2011-03-21 10:29 1281为什么必须用IOC(DI ... -
原来有关Spring核心部分的源代码分析
2011-02-23 09:19 1044原来有关Spring核心部分的源代码分析,比较乱,而且没有整理 ... -
Spring框架核心源代码的分析及其感受-IOC篇-4
2010-11-13 16:34 2529从上一篇,我知道了我 ... -
Spring框架核心源代码的分析及其感受-IOC篇-3
2010-11-13 16:09 3054在上一篇中,我们找到了doCreateBean方法,我绕了半圈 ... -
Spring框架核心源代码的分析及其感受-IOC篇-2
2010-11-13 15:51 2164在上一篇,我们看到这样的代码: DefaultLis ... -
Spring框架核心源代码的分析及其感受-IOC篇-1
2010-11-13 15:29 2205首先,必须先在[/size]Spring源代码中,找到IOC的 ... -
Spring框架核心源代码的分析及其感受-6
2010-11-12 15:53 1550} else ... -
Spring框架核心源代码的分析及其感受-5
2010-11-12 15:50 1721this . readerContext .getR ... -
Spring框架核心源代码的分析及其感受-4
2010-11-12 15:47 1679好了!这里又出现了新的类型 BeanDefinitionPa ... -
Spring框架核心源代码的分析及其感受-3
2010-11-12 15:44 1633protected void loadBeanDefiniti ... -
Spring框架核心源代码的分析及其感受-2
2010-11-12 15:38 1964呵呵,无论从调用关系、方法名称和注释都能敏感的感觉到找对地方了 ...
相关推荐
白色简洁风格的学术交流会议源码下载.zip
内容概要:本文提出了利用交变电流场测量(ACFM)技术对水下结构中的缺陷进行可视化和智能识别的方法。通过对缺陷引起畸变磁场的分析,开发了梯度成像算法作为图像预处理方法,突显了缺陷的视觉形态。实验验证了梯度成像算法的有效性,并利用卷积神经网络(CNN)深度学习算法识别预处理后的灰度图样本。实验结果显示,电流扰动理论澄清了特征信号与缺陷形态之间的关系,单裂纹、不规则裂纹和腐蚀等缺陷可以被智能识别和准确评估。 适合人群:从事水下结构检测的研究人员和技术人员,以及对非破坏性检测技术感兴趣的工程领域人士。 使用场景及目标:① 海洋钻井平台、管道、海底油气处理设施等水下结构的缺陷检测;② 利用交变电流场测量技术和图像处理技术提高缺陷识别的准确性和智能化程度。 其他说明:本文不仅提出了交变电流场测量技术的新方法,还通过实验证明了这些方法的有效性,为实际应用提供了技术支持。
Neck Deep - In Bloom [mqms2].mgg2.flac
基于ESO的永磁同步电机无感FOC 1.采用线性扩张状态观测器(LESO)估计电机反电势,利用锁相环从反电势中提取位置和转速信息,从而实现无位置传感器控制; 2.提供算法对应的参考文献和仿真模型。 购买赠送PMSM控制相关电子资料。 仿真模型纯手工搭建,不是从网络上复制得到。 仿真模型仅供学习参考。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
三相逆变 单相 三相逆变器 SPWM ---stm32主控(输入、输出具体可根据需要设定),本逆变器可以二次开发。 本内容只包括 逆变程序,实现变频(0~100Hz)、变压调节,均有外接按键控制(使用C语言实现)。
NSConditionException如何解决.md
白色简洁风格的房产交易中心企业网站源码下载.zip
水果分拣机15可编辑全套技术资料100%好用.zip
内容概要:本文为《1+X移动互联网应用开发初级》课程的期中考试试卷解析。解析涵盖了Java开发入门基础知识,主要包括Android中SQLite数据库操作、ContentProvider使用、BroadcastReceiver、Intent传递数据、Activity生命周期、Service生命周期管理、文件操作模式、通知管理、JSON和XML解析、权限管理等内容。通过对各个题目的解析,帮助学生更好地理解和掌握移动互联网应用开发的基础知识和技术。 适合人群:正在学习《1+X移动互联网应用开发初级》课程的学生,尤其是网络21班的学生。 使用场景及目标:①帮助学生理解和掌握Android开发的基础知识点;②提高学生的实际操作能力,尤其是在期中考试后的查漏补缺。 阅读建议:建议学生在阅读解析时,结合教材和实践操作,加深对各知识点的理解。同时,可以通过模拟题进行练习,巩固学习成果。
自动送料切割机sw可编辑全套技术资料100%好用.zip
ClosedChannelException(解决方案).md
长焊缝打磨机step全套技术资料100%好用.zip
从给定的文件信息来看,核心知识点聚焦于内部审计业务的实施,特别是内部审计师如何遵循规范、标准和最佳实践来进行审计工作。以下是对关键知识点的深入解析: ### 内部审计业务实施的关键要素 #### 理解内部审计业务全过程 内部审计业务覆盖了从计划、实施、报告到后续跟踪的全过程,要求内部审计师具备全面的专业技能和严谨的工作态度。这一过程旨在确保组织的风险管理、控制和治理机制的有效性。 #### 核心业务类型 内部审计主要包括确认和咨询两大业务类型。确认服务侧重于评估组织的控制和风险管理程序,而咨询服务则更注重提供改进和优化现有流程的建议。 ### 实施内部审计的依据与标准 #### IIA职业实务框架 - **标准与道德规范**:包括内部审计实务标准和职业道德规范,前者指导内部审计活动的执行,后者强调审计师的公正、客观、保密和胜任能力。 - **实务公告**:提供非强制性的指导,涉及内部审计的特定操作流程和程序。 - **发展与实务帮助**:涵盖各种专业资源,如研究资料、书籍和培训课程,为审计人员提供深入的学习和支持。 #### 法律、法规和其他标准 除了IIA框架外,内部审计还应考虑适用
IncompatibleClassChangeError(解决方案).md
html渲染器,粘贴html代码到这个渲染器即可渲染出对应的效果
白色简洁风格的时尚宝马老爷车企业网站模板下载.zip
白色宽屏风格的贸易商务企业网站模板.zip
白色宽屏风格的旅游路线推荐整站网站源码下载.zip
白色简洁风格的社交博客网站后台系统源码下载.zip
实惠 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Calculater extends JFrame implements ActionListener。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。