倒置控制的几个重要好处。如:
. 因为组件不需要在运行时间寻找合作者,所以他们可以更简单的编写和维护。在Spring的IoC版本里,组件通过暴露JavaBean的setter方法表达他们依赖的其他组件。这相当于EJB通过JNDI来查找,EJB查找需要开发人员编写代码。
. 同样原因,应用代码更容易测试。JavaBean属性是简单的,Java核心的,并且容易测试:仅编写一个包含自身的Junit测试方法用来创建对象和设置相关属性即可。
. 一个好的IoC实现隐藏了强类型。如果你使用一个普通的factory来寻找合作者,你必须通过类型转换将返回结果转变为想要的类型。这不是一个主要问题,但是不雅观。使用IoC,你在你的代码中表达强类型依赖,框架将负责类型转换。这意味着在框架配置应用时,类型不匹配将导致错误;在你的代码中,你无需担心类型转换异常。
. 大部分业务对象不依赖于IoC容器的APIs。这使得很容易使用遗留下来的代码,且很容易的使用对象无论在容器内或不在容器内。例如,Spring用户经常配置Jakarta Commons DBCP数据源为一个Spring bean:不需要些任何定制代码去做这件事。我们说一个IoC容器不是侵入性的:使用它并不会使你的代码依赖于它的APIs。任何JavaBena在Spring bean factory中都能成为一个组件。
最后应该强调的是,IoC 不同于传统的容器的体系结构( 如EJB), 应用代码最小程度的依靠于容器。这意味着你的业务对象可以潜在的被运行在不同的IoC 框架上-或者在任何框架之外-不需要任何代码改。
以我的经验和作为Spring用户,过分强调IoC给应用代码带来的好处是不容易的。
IoC不是一个新概念,但是它在J2EE团体里面刚刚到达黄金时间。 有一些可供选择的IoC 容器: notably, Apache Avalon, PicoContainer 和 HiveMind. Avalon 不会成为特别流行的,尽管它很强大而且有很长的历史。Avalon是相当的重量级和复杂的,并且看起来比新的IoC解决方案更具侵入性。 PicoContainer是一个轻量级而且更强调通过构造器表达依赖性而不是JavaBean 属性。 与Spring不同,它的设计允许每个类型一个对象的定义(可能局限性结果来自它对Java代码外的元数据的拒绝)。作为和Spring and PicoContainer and other IoC frameworks的比较,可参看文章
http://www.springframework.org/docs/lightweight_container.html. 这个业面包含了PicoContainer站点链接 。
Spring BeanFactories 是非常轻量级的。用户已经成功地将他们应用在applets中和单独的Swing应用中。(它们也很好地工作在EJB容器中。) 没有特殊的部署步骤和可察觉的启动时间。这个能力表明一个容器在应用的任何层面差不多立即可以发挥非常大的价值。
Spring BeanFactory 概念应用贯穿于Spring整体, 而且是Spring如此内在一致的关键原因。在IoC容器中,Spring也是唯一的,它使用IoC作为基础概念贯穿于整个框架。
对应用开发人员,最重要的是,一个或多个BeanFactory提供一个定义明确的业务对象层。这是类似的,但比local session bean层更简单。与EJBs不同,在这个层中的对象可能是相关的,并且他们的关系被自己的factory管理。有一个定义明确的业务对象层对于一个成功的体系结构是非常重要的。
Spring ApplicationContext 是BeanFactory的子接口,为下列提供支持:
.消息寻找,国际化支持
.事件机制,允许应用对象发布和随意地注册为事件监听
.便携文件和资源访问
XmlBeanFactory示例
Spring用户通常在XML“bean定义”文件中配置他们的应用。Spring的XML bean定义文档的根是一个<beans> 元素。该元素包含一个或多个 <bean>定义。我们一般指定一个bean定义的类和属性。我们也必须指定ID作为标识,我们将在代码中使用该标志。
让我们来看一个简单的例子,在J2EE应用中常看到用来配置三个应用对象:
. J2EE DataSource
. 使用DataSource的DAO
. 在处理过程中使用DAO的业务对象
在下面的例子中,我们使用一个来自Jakarta Commons DBCP项目的BasicDataSource。这个class(和其他存在的class一样)可以简单地被应用在Spring bean factory中,因为它提供了JavaBean格式的配置。需要在shutdown时被调用的Close方法可通过Spring的"destroy-method"属性被注册,来避免BasicDataSource需要实现任何Spring 接口。
代码:
<beans>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/mydb</value></property>
<property name="username"><value>root</value></property>
</bean>
我们感兴趣的BasicDataSource的所有属性都是String型的,因此,我们用<value>元素来指定他们的值。如果必要的话,Spring使用标准的 JavaBean属性编辑器机制来转换String以表示其他的类型。
现在,我们定义了DAO,它有一个对DataSource的bean引用。Bean间关系通过<ref>元素来指定:
代码:
<bean id="exampleDataAccessObject" class="example.ExampleDataAccessObject">
<property name="dataSource">
<ref bean="myDataSource"/>
</property>
</bean>
业务对象有一个DAO的引用和一个int型属性(exampleParam):
代码:
<bean id="exampleBusinessObject" class="example.ExampleBusinessObject">
<property name="dataAccessObject"><ref bean="exampleDataAccessObject"/></property>
<property name="exampleParam"><value>10</value></property>
</bean>
</beans>
对象间的关系一般在配置中明确地设置,象此例子一样。我们认为这样做是件好事情。无论如何,Spring也提供了我们叫做"autowire"的支持, 一个la PicoContainer,在那里,它可以指出bean间的依赖关系。这样做的局限性-如使用PicoContainer-是如果有一个特殊类型的多个Bean,要作出一个类型应该与哪个实例相关的判断将是不可能的。好的方面,在factory初始化后,不理想的依赖可能会被捕获到。(Spring 也为清楚的配置提供一种可选的依赖检查,它可以完成这个目的)
如果我们不想明确的编写他们的关系,在上面的例子中,我们可如下使用autowire特性:
<bean id="exampleBusinessObject" class="example.ExampleBusinessObject" autowire="byType">
<property name="exampleParam"><value>10</value></property>
</bean>
使用这用用法,Spring将找出exampleBusinessObject的dataSource属性应该被设置为在当前BeanFactory中找到的DataSource实现。在当前的BeanFactory中,如果所需要类型的bean不存在或多于一个,将产生一个错误。我们依然要设置exampleParam属性,因为它不是一个引用。
Autowire支持和依赖检查刚刚加入CVS并将在Spring 1.0 M2(到10/20,2003)中提供。本文中所讨论的所有其他特性都包含在当前1.0 M1版本中。
来自Java代码的外在关系比硬编码有极大的好处,因为改变XML文件而无需改变一行Java代码是可能的。例如,我们可以简单地改变myDataSource的bean定义来提供不同的bean class以使用一个可供选择的连接池,或者一个测试数据源。 在一个单独可选的XML片断中,我们可以用Spring的JNDI 定位FactoryBean来从application server获取一个数据源。
现在让我们来看例子中业务对象的java 代码。注意下面列出的代码中没有对Spring的依赖。不像EJB容器,Spring BeanFactory不是侵入性的:在应用对象里面你通常不需要对他们编码。
代码:
public class ExampleBusinessObject implements MyBusinessObject {
private ExampleDataAccessObject dao;
private int exampleParam;
public void setDataAccessObject(ExampleDataAccessObject dao) {
this.dao = dao;
}
public void setExampleParam(int exampleParam) {
this.exampleParam = exampleParam;
}
public void myBusinessMethod() {
// do stuff using dao
}
}
注意属性设置器,在bean定义文档中,它对应与XML引用。这些将在对象使用之前被Spring调用.
这些应用bean不需要依赖于Spring。他们不需要实现任何Spring接口或者继承Spring的类:他们只需要遵守JavaBeans命名习惯。在Spring 应用环境之外重用它们是非常简单的,例如,一个测试环境。只是例示它有默认的构造器,并且通过setDataSource()和setExampleParam()的调用来手工设置它的属性。只要你有一个没有参数的构造器,如果你想在单行代码支持程序化的创建,你可以自由定义其他的带有多个属性构建的器。
注意,在业务接口中没有声明的JavaBean属性将会一起工作。 他们是一个实现细节。我们可以插入带有不同bean属性的不同的实现类而不影响连接对象或者调用代码。
当然,Spring XML bean factories 有更多的功能没有在这里描述,但是,这将给你一种基本使用的感觉。同时,简单的属性和有JavaBean属性编辑器的属性,Spring可以自动处理lists,maps和java.util.Properties.
分享到:
相关推荐
整个系统以单片 机为核心,设计出硬件系统"以其中的几个口控制驱动电路,由于步进电机工作时,电机 绕组内的电流值一般都能达到数安培,而控制电机绕组内电流变化的控制信号一般都是 由逻辑电路产生的数字信号,电压...
需要说明的一点,BasicOS不是一个抢占式的RTOS,它遵循几个重要原则,简单,易用,低资源占用,因此它取名为Basic。 为什么要为BasicOS开发共享栈这个特性? 在开发BasicOS这个项目之前,狗哥先开发了EventOS和...
系统由以下几部分构成:①单片机:设计的核心,在软件的配合下实现对键盘所输入信息的识别,根据输入信息向云台中的步进电机发出指令,使其实现正/ 反转、速度控制、程序控制等功能,并将步进电机的转速通过数码管...
实际要理解一个框架的类型,还是要自己看源码,这里我只说一下几个重要类型的作用,这个看源码的时候有个印象,也方便理解,而且说这部分的帖子也很多,我就不再赘述了。 1.Context 上下文组件定义程序边界,也就是...
智能车库门就是自动控制应用的以典型例子,由于可编程控制器具有很好的处理智能 车库门开关控制及良好的稳定性,而且可以很简单的改变控制的方式,因此,智能车库 门的生产商家很多都运用PLC来做门的控制器。...
选择动画处理一个或几个元素,将观看者的目光吸引到想让照片变活的任何部分。 屡获大奖的 Enlight 创作套件的开发厂商 Lightricks 为您带来:Enlight Photofox、Enlight Quickshot 和 Enlight Videoleap(Apple ...
线反转法可以可到防止几个单 触点开关同时按下对硬件的损害,起到保护作用。 线反转法的工作原理 如下: 首先将行线作为输出线,列线作为输入线。先通过行线输出全"0"信号,读入列线的值。 如果此时有某一个键被按下...
如果给步进电机发送一个控制脉冲,它就转一步,再发送一个脉冲,它会再转一步。两个脉冲的间隔越短,步进电机就转的越快。调整单片机发出的脉冲频率,就可以对步进电机进行调速。 2.2.2 步进电机主要技术指标 选择...
java面试题笔试题Spring面试指南 - 200+ 问答 Spring 框架是有史以来最流行的 ...你能举几个依赖注入的例子吗? 什么是汽车布线? IOC Container 的重要作用是什么? 什么是 Bean 工厂和应用程序上下文? 你能
3个按键分别控制电机正转、反转及停止,LED指示在发送报文时闪烁;当无按键按下时,约10秒后进入低功耗状态,有按键按键自动退出低功耗状态(通过外部中断唤醒MCU),通过433MHz无线模块发送按键码。 控制部分主要由...
第1章 应重视的价值,也是对过去几年的沉重反思 1.1 总体价值 1.2 应重视的架构风格 1.2.1 焦点之一:模型 1.2.2 焦点之二:用例 1.2.3 如果重视模型,就可以使用领域模型模式 1.2.4 慎重处理数据库 1.2.5 领域模型...
最近跟着B站的狂神学习了Spring的大概,以前有过写传统JavaWeb的经验,现在也算是进阶学习框架吧,这篇博客主要记录一下Spirng中的两个重要思想之一——IOC,控制反转 大体思想 在开发的过程中,当体量较小时,用户...
7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格...
与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决网页和JS文件中的中文编码问题的小工具 慎用const...
1分钟内能处理手工需几小时才能完成的几万行ERP或KingDee原始数据。极力推荐的工具之一。 【取唯一值】 能瞬间取任意存储格区域的内容为不含重复值的唯一值清单,加载到工具中并提供随时随地调用,具有重复加载与...
7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格...
7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格...
7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格...
7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格...