多图详解Spring框架的设计理念与设计模式

上传人:卷*** 文档编号:128045949 上传时间:2022-07-31 格式:DOC 页数:47 大小:665KB
返回 下载 相关 举报
多图详解Spring框架的设计理念与设计模式_第1页
第1页 / 共47页
多图详解Spring框架的设计理念与设计模式_第2页
第2页 / 共47页
多图详解Spring框架的设计理念与设计模式_第3页
第3页 / 共47页
点击查看更多>>
资源描述
Spring作为目前最优秀的框架之一,已被广泛的使用,51CTO也曾经针对Spring框架中的JDBC应用做过报道。本文将从此外一种视角试图剖析出Spring框架的作者设计Spring框架的骨骼架构的设计理念。Rod Johson在编著的Expert one to one J2EE design and development一书中,对Java EE正统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极谋求摸索革新之道。以此书为指引思想,她编写了interface21框架,这是一种力图冲破Java EE老式开发的困境,从实际需求出发,着眼于轻便、机灵,易于开发、测试和部署的轻量级开发框架。Spring框架即以interface21框架为基本,通过重新设计,并不断丰富其内涵,于3月24日,发布了1.0正式版。同年她又推出了一部堪称典型的力作Expert one-to-one J2EE Development without EJB,该书在Java世界掀起了轩然大波,不断变化着Java开发者程序设计和开发的思考方式。在该书中,作者根据自己近年丰富的实践经验,对EJB 的多种笨重臃肿的构造进行了逐个的分析和否认,并分别以简洁实用的方式替代之。至此一战功成,Rod Johnson成为一种变化Java世界的大师级人物。老式J2EE应用的开发效率低,应用服务器厂商对多种技术的支持并没有真正统一,导致J2EE的应用没有真正实现Write Once及Run Anywhere的承诺。Spring作为开源的中间件,独立于多种应用服务器,甚至不必应用服务器的支持,也能提供应用服务器的功能,如声明式事务等。Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是公司应用开发的“一站式”选择,并贯穿体现层、业务层及持久层。然而,Spring并不想取代那些已有的框架,而与它们无缝地整合。Spring简介Spring是一种开源框架,它由Rod Johnson创立。它是为理解决公司应用开发的复杂性而创立的。Spring使用基本的JavaBean来完毕此前只也许由EJB完毕的事情。然而,Spring的用途不仅限于服务器端的开发。从简朴性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。目的:解决公司应用开发的复杂性功能:使用基本的JavaBean替代EJB,并提供了更多的公司应用功能范畴:任何Java应用简朴来说,Spring是一种轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。轻量从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一种大小只有1MB多的JAR文献里发布。并且 Spring所需的解决开销也是微局限性道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。控制反转Spring通过一种称作控制反转(IoC)的技术增进了松耦合。当应用了IoC,一种对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创立或者查找依赖对象。你可以觉得IoC与JNDI相反不是对象沉着器中查找依赖,而是容器在对象初始化时不等对象祈求就积极将依赖传递给它。面向切面Spring提供了面向切面编程的丰富支持,容许通过度离应用的业务逻辑与系统级服务(例如审计(auditing)和事务()管理)进行内聚性的开发。应用对象只实现它们应当做的完毕业务逻辑仅此而已。它们并不负责(甚至是意识)其他的系统级关注点,例如日记或事务支持。容器Spring涉及并管理应用对象的配备和生命周期,在这个意义上它是一种容器,你可以配备你的每个bean如何被创立基于一种可配备原型(prototype),你的bean可以创立一种单独的实例或者每次需要时都生成一种新的实例以及它们是如何互相关联的。然而,Spring不应当被混淆于老式的重量级的EJB容器,它们常常是庞大与笨重的,难以使用。框架Spring可以将简朴的组件配备、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一种XML文献里。Spring也提供了诸多基本功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。所有Spring的这些特性使你可以编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的多种模块提供了基本支持。为什么需要Spring你也许正在想“Spring但是是此外一种的framework”。当已有许多开放源代码(和专有) J2EE framework时,我们为什么还需要Spring Framework?Spring是独特的,由于若干个因素:它定位的领域是许多其她流行的framework没有的。Spring关注提供一种措施管理你的业务对象。 Spring是全面的和模块化的。Spring有分层的体系构造,这意味着你能选择使用它孤立的任何部分,它的架构仍然是内在稳定的。因此从你的学习中,你可得到最大的价值。例如,你也许选择仅仅使用Spring来简朴化JDBC的使用,或用来管理所有的业务对象。它的设计从底部协助你编写易于测试的代码。Spring是用于测试驱动工程的抱负的framework。Spring对你的工程来说,它不需要一种以上的framework。Spring是潜在地一站式解决方案,定位于与典型应用有关的大部分基本构造。它也波及到其她framework没有考虑到的内容。Spring带给我们什么以便解耦,简化开发,通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所导致的过度程序耦合。有了Spring,顾客不必再为单实例模式类、属性文献解析等这些很底层的需求编写代码,可以更专注于上层的应用。AOP编程的支持通过Spring提供的AOP功能,以便进行面向切面的编程,许多不容易用老式OOP实现的功能可以通过AOP轻松应付。声明式事务的支持在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。以便程序的测试可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。以便集成多种优秀框架Spring不排斥多种优秀的开源框架,相反,Spring可以减少多种框架的使用难度,Spring提供了对多种优秀框架(如Struts,Hibernate、Hession、Quartz)等的直接支持。减少Java EE API的使用难度Spring对诸多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一种薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为减少。Java 源码是典型学习范例Spring的源码设计精妙、构造清晰、匠心独用,到处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。Spring框架的好处在我们进入细节此前,让我们看一下Spring可以给一种工程带来的某些好处:Spring能有效地组织你的中间层对象,无论你与否选择使用了EJB。如果你仅仅使用了Struts或其她的涉及了J2EE特有APIs的framework,你会发现Spring关注了遗留下的问题,。Spring能消除在许多工程上对Singleton的过多使用。根据我的经验,这是一种重要的问题,它减少了系统的可测试性和面向对象特性。Spring能消除使用多种各样格式的属性定制文献的需要,在整个应用和工程中,可通过一种一致的措施来进行配备。曾经感到困惑,一种特定类要查找迷幻般的属性核心字或系统属性,为此不得不读Javadoc乃至源编码吗?有了Spring,你可很简朴地看到类的JavaBean属性。倒置控制的使用(在下面讨论)协助完毕这种简化。Spring能通过接口而不是类增进好的编程习惯,减少编程代价到几乎为零。Spring被设计为让使用它创立的应用尽量少的依赖于她的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。使用Spring构建的应用程序易于单元测试。Spring能使EJB的使用成为一种实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。Spring协助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替代物,它们适于许多web应用。例如,Spring能使用AOP提供声明性事务而不通过使用EJB容器,如果你仅仅需要与单个的数据库打交道,甚至不需要JTA实现。Spring为数据存取提供了一致的框架,不管是使用JDBC或O/R mapping产品(如Hibernate)。Spring的确使你能通过最简朴可行的解决措施解决你的问题。这些特性是有很大价值的。总结起来,Spring有如下长处:低侵入式设计,代码污染极低独立于多种应用服务器,可以真正实现Write Once,Run Anywhere的承诺Spring的DI机制减少了业务对象替代的复杂性Spring并不完全依赖于Spring,开发者可自由选用Spring框架的部分或所有Spring能做什么?Spring提供许多功能,在此我将迅速地依次展示其各个重要方面。一方面,让我们明确Spring范畴。尽管Spring覆盖了许多方面,但我们已有清晰的概念,它什么应当波及和什么不应当波及。Spring的重要目的是使J2EE易用和增进好编程习惯。Spring不重新开发已有的东西。因此,在Spring中你将发现没有日记记录的包,没有连接池,没有分布事务调度。这些均有开源项目提供 (例如Commons Logging 用来做所有的日记输出,或Commons DBCP用来作数据连接池),或由你的应用程序服务器提供。由于同样的的因素,我们没有提供O/R mapping层,对此,已有有好的解决措施如Hibernate和JDO。Spring的目的是使已存在的技术更加易用。例如,尽管我们没有底层事务协调解决,但我们提供了一种抽象层覆盖了JTA或任何其她的事务方略。Spring没有直接和其她的开源项目竞争,除非我们感到我们能提供新的某些东西。例如,象许多开发人员,我们历来没有为Struts快乐过,并且感到在MVC web framework中尚有改善的余地。在某些领域,例如轻量级的IoC容器和AOP框架,Spring有直接的竞争,但是在这些领域还没有已经较为流行的解决方案。(Spring在这些区域是开路先锋。)Spring也得益于内在的一致性。所有的开发者都在唱同样的的赞歌,基本想法仍然是Expert One-on-One J2EE设计与开发的那些。并且我们已经可以使用某些重要的概念,例如倒置控制,来解决多种领域。Spring在应用服务器之间是可移植的。固然保证可移植性总是一次挑战,但是我们避免任何特定平台或非原则化,并且支持在WebLogic,Tomcat,Resin,JBoss,WebSphere和其她的应用服务器上的顾客。 Spring作为目前最优秀的框架之一,已被广泛的使用,51CTO也曾经针对Spring框架中的JDBC应用做过报道。本文将从此外一种视角试图剖析出Spring框架的作者设计Spring框架的骨骼架构的设计理念,有那几种核心组件?为什么需要这些组件?它们又是如何结合在一起构成Spring的骨骼架构?Spring的AOP特性又是如何运用这些基本的骨骼架构来工作的?Spring中又使用了那些设计模式来完毕它的这种设计的?它的这种 设计理念对对我们后来的软件设计有何启示?本文将具体解答这些问题。Spring的骨骼架构Spring总共有十几种组件,但是真正核心的组件只有几种,下面是Spring框架的总体架构图:图1.Spring框架的总体架构图从上图中可以看出Spring框架中的核心组件只有三个:Core、Context和Beans。它们构建起了整个Spring的骨骼架构。没有它们就不也许有AOP、Web等上层的特性功能。下面也将重要从这三个组件入手分析Spring。Spring的设计理念前面简介了Spring的三个核心组件,如果再在它们三个中选出核心的话,那就非Beans组件莫属了,为什么这样说,其实Spring就是面向Bean的编程(BOP,Bean Oriented Programming),Bean在Spring 中才是真正的主角。Bean在Spring中作用就像Object对OOP的意义同样,没有对象的概念就像没有面向对象编程,Spring中没有Bean也就没有Spring存在的意义。就像一次表演舞台都准备好了但是却没有演员同样。为什 么要Bean这种角色Bean或者为什么在Spring如此重要,这由Spring框架的设计目的决定,Spring为什么如此流行,我们用Spring的因素是什么,想想你会发现本来Spring解决了一种非常核心的问题她可以让 你把对象之间的依赖关系转而用配备文献来管理,也就是她的依赖注入机制。而这个注入关系在一种叫Ioc容器中管理,那Ioc容器中有又是什么就是被Bean包裹的对象。Spring正是通过把对象包装在 Bean中而达到对这些对象管理以及某些列额外操作的目的。它这种设计方略完全类似于Java实现OOP的设计理念,固然了Java自身的设计要比Spring复杂太多太多,但是都是构建一种数据构造,然后根据这个数据构造设计她的生存环境,并让它在这个环境中 按照一定的规律在不断的运动,在它们的不断运动中设计一系列与环境或者与其她个体完毕信息互换。这样想来回过头想想我们用到的其她框架都是大慨类似的设计理念。核心组件如何协同工作前面说Bean是Spring中核心因素,那Context和Core又有何作用呢?前面吧Bean比作一场表演中的演员的话,那Context就是这场表演的舞台背景,而Core应当就是表演的道具了。只有她们在一起才干 具有能表演一场好戏的最基本的条件。固然有最基本的条件还不能使这场表演脱颖而出,还要她表演的节目足够的精彩,这些节目就是Spring能提供的特色功能了。我们懂得Bean包装的是Object,而Object必然有数据,如何给这些数据提供生存环境就是Context要解决的问题,对Context来说她就是要发现每个Bean之间的关系,为它们建立这种关系并且要维护好 这种关系。因此Context就是一种Bean关系的集合,这个关系集合又叫Ioc容器,一旦建立起这个Ioc容器后Spring就可觉得你工作了。那Core组件又有什么用武之地呢?其实Core就是发现、建立和维护每 个Bean之间的关系所需要的某些列的工具,从这个角度看来,Core这个组件叫Util更能让你理解。它们之间可以用下图来表达:图2.三个组件关系核心组件详解这里将具体简介每个组件内部类的层次关系,以及它们在运营时的时序顺序。我们在使用Spring是应当注意的地方。Bean组件前面已经阐明了Bean组件对Spring的重要性,下面看看Bean这个组件式怎么设计的。Bean组件在Spring的org.springframework.beans包下。这个包下的所有类重要解决了三件事:Bean的定义、Bean 的创立以及对Bean的解析。对Spring的使用者来说唯一需要关怀的就是Bean的创立,其她两个由Spring在内部帮你完毕了,对你来说是透明的。SpringBean的创立时典型的工厂模式,她的顶级接口是BeanFactory,下图是这个工厂的继承层次关系:图4.Bean工厂的继承关系BeanFactory有三个子类:ListableBeanFactory、HierarchicalBeanFactory和Autowire Capable Bean Factory。但是从上图中我们可以发现最后的默认实现类是DefaultListableBeanFactory,她实 现了所有的接口。那为什么要定义这样多层次的接口呢?查阅这些接口的源码和阐明发现,每个接口均有她使用的场合,它重要是为了辨别在Spring内部在操作过程中对象的传递和转化过程中,对对象的 数据访问所做的限制。例如ListableBeanFactory接口表达这些Bean是可列表的,而HierarchicalBeanFactory表达的是这些Bean是有继承关系的,也就是每个Bean有也许有父Bean。 AutowireCapableBeanFactory接口定义Bean的自动装配规则。这四个接口共同定义了Bean的集合、Bean之间的关系、以及Bean行为。Bean的定义重要有BeanDefinition描述,如下图阐明了这些类的层次关系:图5.Bean定义的类层次关系图Bean的定义就是完整的描述了在Spring的配备文献中你定义的节点中所有的信息,涉及多种子节点。当Spring成功解析你定义的一种节点后,在Spring的内部她就被转化 成BeanDefinition对象。后来所有的操作都是对这个对象完毕的。Bean的解析过程非常复杂,功能被分的很细,由于这里需要被扩展的地方诸多,必须保证有足够的灵活性,以应对也许的变化。Bean的解析重要就是对Spring配备文献的解析。这个解析过程重要通过 下图中的类完毕:图6.Bean的解析类固然尚有具体对tag的解析这里并没有列出。Context组件Context在Spring的org.springframework.context包下,前面已经解说了Context组件在Spring中的作用,她事实上就是给Spring提供一种运营时的环境,用以保存各个对象的状态。下面看一下这个 环境是如何构建的。ApplicationContext是Context的顶级父类,她除了能标记一种应用环境的基本信息外,她还继承了五个接口,这五个接口重要是扩展了Context的功能。下面是Context的类构造图:图7.Context有关的类构造图从上图中可以看出ApplicationContext继承了BeanFactory,这也阐明了Spring容器中运营的主体对象是Bean,此外ApplicationContext继承了ResourceLoader接口,使得ApplicationContext可以访 问到任何外部资源,这将在Core中具体阐明。ApplicationContext的子类重要涉及两个方面:ConfigurableApplicationContext表达该Context是可修改的,也就是在构建Context中顾客可以动态添加或修改已有的配备信息,它下面又有多种子类,其中最常常使用的是可更新的Context,即 AbstractRefreshableApplicationContext类。WebApplicationContext顾名思义,就是为web准备的Context她可以直接访问到ServletContext,一般状况下,这个接口使用的少。再往下分就是按照构建Context的文献类型,接着就是访问Context的方式。这样一级一级构成了完整的Context级别层次。总体来说ApplicationContext必须要完毕如下几件事:标记一种应用环境运用BeanFactory创立Bean对象保存对象关系表可以捕获多种事件Context作为Spring的Ioc容器,基本上整合了Spring的大部分功能,或者说是大部分功能的基本。Core组件Core组件作为Spring的核心组件,她其中涉及了诸多的核心类,其中一种重要构成部分就是定义了资源的访问方式。这种把所有资源都抽象成一种接口的方式很值得在后来的设计中拿来学习。下面就 重要看一下这个部分在Spring的作用。下图是Resource有关的类构造图:图8.Resource有关的类构造图从上图可以看出Resource接口封装了多种也许的资源类型,也就是对使用者来说屏蔽了文献类型的不同。对资源的提供者来说,如何把资源包装起来交给其她人用这也是一种问题,我们看到Resource 接口继承了InputStreamSource接口,这个接口中有个getInputStream措施,返回的是InputStream类。这样所有的资源都被可以通过InputStream这个类来获取,因此也屏蔽了资源的提供者。此外尚有一 个问题就是加载资源的问题,也就是资源的加载者要统一,从上图中可以看出这个任务是由ResourceLoader接口完毕,她屏蔽了所有的资源加载者的差别,只需要实现这个接口就可以加载所有的资源, 她的默认实现是DefaultResourceLoader。下面看一下Context和Resource是如何建立关系的?一方面看一下她们的类关系图:图9.Context和Resource的类关系图从上图可以看出,Context是把资源的加载、解析和描述工作委托给了ResourcePatternResolver类来完毕,她相称于一种接头人,她把资源的加载、解析和资源的定义整合在一起便于其她组件使用。 Core组件中尚有诸多类似的方式。Ioc容器如何工作前面简介了Core组件、Bean组件和Context组件的构造与互相关系,下面这里从使用者角度看一下她们是如何运营的,以及我们如何让Spring完毕多种功能,Spring究竟能有那些功能,这些功能是如 何得来的,下面简介。如何创立BeanFactory工厂正如图2描述的那样,Ioc容器事实上就是Context组件结合其她两个组件共同构建了一种Bean关系网,如何构建这个关系网?构建的入口就在AbstractApplicationContext类的refresh措施中。这个方 法的代码如下:清单1.AbstractApplicationContext.refresh1. publicvoidrefresh()throwsBeansException,IllegalStateException 2. 3. synchronized(this.startupShutdownMonitor) 4. 5. /Preparethiscontextforrefreshing. 6. 7. prepareRefresh(); 8. 9. /Tellthesubclasstorefreshtheinternalbeanfactory. 10. 11. ConfigurableListableBeanFactorybeanFactory=obtainFreshBeanFactory(); 12. 13. /Preparethebeanfactoryforuseinthiscontext. 14. 15. prepareBeanFactory(beanFactory); 16. 17. try 18. 19. /Allowspost- processingofthebeanfactoryincontextsubclasses. 20. 21. postProcessBeanFactory(beanFactory); 22. 23. /Invokefactoryprocessorsregisteredasbeansin& nbsp;thecontext. 24. 25. invokeBeanFactoryPostProcessors(beanFactory); 26. 27. /Registerbeanprocessorsthatinterceptbeancrea tion. 28. 29. registerBeanPostProcessors (beanFactory); 30. 31. /Initializemessagesourceforthiscontext. 32. 33. initMessageSource(); 34. 35. /Initializeeventmulticasterforthiscontext. 36. 37. initApplicationEventMulticaster(); 38. 39. /Initializeotherspecialbeansinspecificcontex tsubclasses. 40. 41. onRefresh(); 42. 43. /Checkforlistenerbeansandregisterthem. 44. 45. registerListeners(); 46. 47. /Instantiateallremaining(non-lazy-init)singletons. 48. 49. finishBeanFactoryInitialization (beanFactory); 50. 51. /Laststep:publishcorrespondingevent. 52. 53. finishRefresh(); 54. 55. 56. 57. catch(BeansExceptionex) 58. 59. /Destroyalreadycreatedsingletonstoavoiddangl ingresources. 60. 61. destroyBeans(); 62. 63. /Resetactiveflag. 64. 65. cancelRefresh(ex); 66. 67. /Propagateexceptiontocaller. 68. 69. throwex; 70. 71. 72. 73. 74. 75. 76. 这个措施就是构建整个Ioc容器过程的完整的代码,理解了里面的每一行代码基本上就理解大部分Spring的原理和功能了。这段代码重要涉及这样几种环节:构建BeanFactory,以便于产生所需的“演员”注册也许感爱好的事件创立Bean实例对象触发被监听的事件下面就结合代码分析这几种过程。第二三句就是在创立和配备BeanFactory。这里是refresh也就是刷新配备,前面简介了Context有可更新的子类,这里正是实现这个功能,当BeanFactory已存在是就更新,如果没有就新创立。下面是 更新BeanFactory的措施代码:清单2. AbstractRefreshableApplicationContext. refreshBeanFactory1. protectedfinalvoidrefreshBeanFactory()throwsBeansException 2. 3. if(hasBeanFactory() 4. 5. destroyBeans(); 6. 7. closeBeanFactory(); 8. 9. 10. 11. try 12. 13. DefaultListableBeanFactorybeanFactory=createBeanFactory(); 14. 15. beanFactory.setSerializationId(getId(); 16. 17. customizeBeanFactory(beanFactory); 18. 19. loadBeanDefinitions(beanFactory); 20. 21. synchronized(this.beanFactoryMonitor) 22. 23. this.beanFactory=beanFactory; 24. 25. 26. 27. 28. 29. catch(IOExceptionex) 30. 31. thrownewApplicationContextException( 32. 33. I/Oerror& nbsp;parsingbeandefinitionsourcefor 34. 35. +getDisplayName (),ex); 36. 37. 38. 39. 40. 这个措施实现了AbstractApplicationContext的抽象措施refreshBeanFactory,这段代码清晰的阐明了BeanFactory的创立过程。注意BeanFactory对象的类型的变化,前 面简介了她有诸多子类,在什么状况下使用不同的子类这非常核心。BeanFactory的原始对象是DefaultListableBeanFactory,这个非常核心,由于她设计到背面对这个对象的多种操作,下面看一下这个 类的继承层次类图:图10.DefaultListableBeanFactory类继承关系图从这个图中发现除了BeanFactory有关的类外,还发现了与Bean的register有关。这在refreshBeanFactory措施中有一行loadBeanDefinitions(beanFactory)将找到答案,这个措施将开始加载、解析 Bean的定义,也就是把顾客定义的数据构造转化为Ioc容器中的特定数据构造。这个过程可以用下面时序图解释:图11.创立BeanFactory时序图Bean的解析和登记流程时序图如下:图12.解析和登记Bean对象时序图创立好BeanFactory后,接下去添加某些Spring自身需要的某些工具类,这个操作在AbstractApplicationContext的prepareBeanFactory措施完毕。AbstractApplicationContext中接下来的三行代码对Spring的功能扩展性起了至关重要的作用。前两行重要是让你目前可以对已经构建的BeanFactory的配备做修改,背面一行就是让你可以对后来再 创立Bean的实例对象时添加某些自定义的操作。因此她们都是扩展了Spring的功能,因此我们要学习使用Spring必须对这一部分弄清晰。其中在invokeBeanFactoryPostProcessors措施中重要是获取实现BeanFactoryPostProcessor接口的子类。并执行它的postProcessBeanFactory措施,这个措施的声明如下:清单3.BeanFactoryPostProcessor.postProcessBeanFactory1. voidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory) 2. 3. throwsBeansException; 它的参数是beanFactory,阐明可以对beanFactory做修改,这里注意这个beanFactory是ConfigurableListableBeanFactory类型的,这也印证了前面简介的不同BeanFactory所使用的场合不同,这里 只能是可配备的BeanFactory,避免某些数据被顾客随意修改。registerBeanPostProcessors措施也是可以获取顾客定义的实现了BeanPostProcessor接口的子类,并执行把它们注册到BeanFactory对象中的beanPostProcessors变量中。BeanPostProcessor中声明 了两个措施:postProcessBeforeInitialization、postProcessAfterInitialization分别用于在Bean对象初始化时执行。可以执行顾客自定义的操作。背面的几行代码是初始化监听事件和对系统的其她监听者的注册,监听者必须是ApplicationListener的子类。如何创立Bean实例并构建Bean的关系网下面就是Bean的实例化代码,是从finishBeanFactoryInitialization措施开始的。清单4.AbstractApplicationContext.finishBeanFactoryInitialization1. protectedvoidfinishBeanFactoryInitialization( 2. 3. ConfigurableListableBeanFactorybeanFactory) 4. 5. 6. 7. /StopusingthetemporaryClassLoaderfortypematching. 8. 9. beanFactory.setTempClassLoader(null); 10. 11. 12. 13. /Allowforcachingallbeandefinitionmetadata,notexpectingfurtherchanges . 14. 15. beanFactory.freezeConfiguration(); 16. 17. 18. 19. /Instantiateallremaining(non-lazy-init)singletons. 20. 21. beanFactory.preInstantiateSingletons(); 22. 23. 24. 从上面代码中可以发现Bean的实例化是在BeanFactory中发生的。preInstantiateSingletons措施的代码如下:清单5.DefaultListableBeanFactory.preInstantiateSingletons25. publicvoidpreInstantiateSingletons()throwsBeansException 26. 27. if(this.logger.isInfoEnabled() 28. 29. this.logger.info(Pre- instantiatingsingletonsin+this); 30. 31. 32. 33. synchronized(this.beanDefinitionMap) 34. 35. for (StringbeanName:this.beanDefinitionNames) 36. 37. RootBeanDefinitionbd=getMergedLocalBeanDefinition(beanName); 38. 39. if(!bd.isAbstract() &bd.isSingleton() 40. 41. &!bd.isLazyInit() 42. 43. if (isFactoryBean(beanName) 44. 45. finalFactoryBeanfactory= 46. 47. (FactoryBean) getBean(FACTORY_BEAN_PREFIX+beanName); 48. 49. booleanisEagerInit; 50. 51. if(System.getSecurityManager() !=null 52. 53. & ;factoryinstanceofSmartFactoryBean) 54. 55. isEagerInit=AccessController.doPrivileged( 56. 57. &nb sp;newPrivilegedAction() 58. 59. &nb sp;publicBooleanrun() 60. 61. return(SmartFactoryBean) factory).isEagerInit(); 62. 63. &nb sp; 64. 65. ,getAcce ssControlContext(); 66. 67. 68. 69. else 70. 71. isEagerInit=factoryinstanceofSmartFactoryBean 72. 73. &nb sp;&(SmartFactoryBean)factory).isEagerInit(); 74. 75. 76. 77. if(isEagerInit) 78. 79. getBean (beanName); 80. 81. 82. 83. 84. 85. else 86. 87. getBean(beanName); 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 这里浮现了一种非常重要的BeanFactoryBean,可以说Spring一大半的扩展的功能都与这个Bean有关,这是个特殊的Bean她是个工厂Bean,可以产生Bean的Bean,这里的产生Bean是指 Bean的实例,如果一种类继承FactoryBean顾客可以自己定义产生实例对象的措施只要实现她的getObject措施。然而在Spring内部这个Bean的实例对象是FactoryBean,通过调用这个对象的getObject方 法就能获取顾客自定义产生的对象,从而为Spring提供了较好的扩展性。Spring获取FactoryBean自身的对象是在前面加上&来完毕的。 如何创立Bean的实例对象以及如何构建Bean实例对象之间的关联关系式Spring中的一种核心核心,下面是这个过程的流程图。 图13.Bean实例创立流程图如果是一般的Bean就直接创立她的实例,是通过调用getBean措施。下面是创立Bean实例的时序图:图14.Bean实例创立时序图尚有一种非常重要的部分就是建立Bean对象实例之间的关系,这也是Spring框架的核心竞争力,何时、如何建立她们之间的关系请看下面的时序图:图15.Bean对象关系建立Ioc容器的扩展点目前尚有一种问题就是如何让这些Bean对象有一定的扩展性,就是可以加入顾客的某些操作。那么有哪些扩展点呢?Spring又是如何调用到这些扩展点的?对Spring的Ioc容器来说,重要有这样几种。BeanFactoryPostProcessor,BeanPostProcessor。她们分别是在构建BeanFactory和构建Bean对象时调用。尚有就是InitializingBean和DisposableBean 她们分别是在Bean实例创立和销毁时被调用。顾客可以实现这些接口中定义的措施,Spring就会在合适的时候调用她们。尚有一种是FactoryBean她是个特殊的Bean,这个Bean可以被顾客更多的控制。这些扩展点一般也是我们使用Spring来完毕我们特定任务的地方,如何精通Spring就看你有无掌握好Spring有哪些扩展点,并且如何使用她们,要懂得如何使用她们就必须理解她们内在的机理。可 以用下面一种比方来解释。我们把Ioc容器比作一种箱子,这个箱子里有若干个球的模子,可以用这些模子来造诸多种不同的球,尚有一种造这些球模的机器,这个机器可以产生球模。那么她们的相应关系就是BeanFactory就是 那个造球模的机器,球模就是Bean,而球模造出来的球就是Bean的实例。那前面所说的几种扩展点又在什么地方呢?BeanFactoryPostProcessor相应到当造球模被造出来时,你将有机会可以对其做出设 当的修正,也就是她可以帮你修改球模。而InitializingBean和DisposableBean是在球模造球的开始和结束阶段,你可以完毕某些预备和扫尾工作。BeanPostProcessor就可以让你对球模造出来的球做出 合适的修正。最后尚有一种FactoryBean,它可是一种神奇的球模。这个球模不是预先就定型了,而是由你来给她拟定它的形状,既然你可以拟定这个球模型的形状,固然她造出来的球肯定就是你想要的 球了,这样在这个箱子里尼可以发现所有你想要的球Ioc容器如何为我所用前面的简介了Spring容器的构建过程,那Spring能为我们做什么,Spring的Ioc容器又能做什么呢?我们使用Spring必须要一方面构建Ioc容器,没有它Spring无法工作,ApplicatonContext.xml就是Ioc 容器的默认配备文献,Spring的所有特性功能都是基于这个Ioc容器工作的,例如背面要简介的AOP。Ioc它事实上就是为你构建了一种魔方,Spring为你搭好了骨骼架构,这个魔方究竟能变出什么好的东西出来,这必须要有你的参与。那我们怎么参与?这就是前面说的要理解Spring中那有些扩展点 ,我们通过实现那些扩展点来变化Spring的通用行为。至于如何实现扩展点来得到我们想要的个性成果,Spring中有诸多例子,其中AOP的实现就是Spring自身实现了其扩展点来达到了它想要的特性功能 ,可以拿来参照。Spring中AOP特性详解动态代理的实现原理要理解Spring的AOP就必须先理解的动态代理的原理,由于AOP就是基于动态代理实现的。动态代理还要从JDK自身说起。在Jdk的java.lang.reflect包下有个Proxy类,它正是构造代理类的入口。这个类的构造入下:图16.Proxy类构造从上图发现最背面四个是公有措施。而最后一种措施newProxyInstance就是创立代理对象的措施。这个措施的源码如下:清单6.Proxy.newProxyInstance1. publicstaticObjectnewProxyInstance(ClassLoaderloader, 2. 3. Class interfaces, 4. 5. InvocationHandlerh) 6. 7. throwsIllegalArgumentException 8. 9. 10. 11. if(h=null)
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!