Spring开发讲解冯广辉2009-07-24一、spring整体架构预览二、spring常用技术注入依赖:原理是对象之间的依赖关系只会通过“构造器的参数”、“工厂方法的参数”或“给由构造函数或者工厂方法创建的对象设置属性”内种方式来实现。●setter注入:通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即可实现基于setter的DI。●构造器注入:基于构造器的DI通过调用带参数的构造器来实现。例:PublicclassXX{…PublicXX(intI,Strings){…}}对应的配置:beanid=“xx”class=“xx”constructor-argtype=“int”value=“1”/constructor-argtype=“java.lang.String’value=“s”//bean常见的几种注入:Type1接口注入:publicclassClassA{privateInterfaceBclzB;publicdoSomething(){Ojbectobj=Class.forName(Config.BImplementation).newInstance();clzB=(InterfaceB)obj;clzB.doIt()}……}Type2设值注入:在各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得力于Spring框架的影响)。Type3构造子注入:publicclassDIByConstructor{privatefinalDataSourcedataSource;privatefinalStringmessage;publicDIByConstructor(DataSourceds,Stringmsg){this.dataSource=ds;}……}在Type3类型的依赖注入机制中,依赖关系是通过类构造函数建立,容器通过调用类的构造方法,将其所需的依赖关系注入其中。几种依赖注入模式的对比总结接口注入模式因为历史较为悠久,在很多容器中都已经得到应用。但由于其在灵活性、易用性上不如其他两种注入模式,因而在IOC的专题世界内并不被看好。Type2和Type3型的依赖注入实现则是目前主流的IOC实现模式。这两种实现方式各有特点,也各具优势(一句经典废话J)。Type2设值注入的优势1.对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系显得更加直观,更加自然。2.如果依赖关系(或继承关系)较为复杂,那么Type3模式的构造函数也会相当庞大(我们需要在构造函数中设定所有依赖关系),此时Type2模式往往更为简洁。3.对于某些第三方类库而言,可能要求我们的组件必须提供一个默认的构造函数(如Struts中的Action),此时Type3类型的依赖注入机制就体现出其局限性,难以完成我们期望的功能。Type3构造子注入的优势:1.“在构造期即创建一个完整、合法的对象”,对于这条Java设计原则,Type3无疑是最好的响应者。2.避免了繁琐的setter方法的编写,所有依赖关系均在构造函数中设定,依赖关系集中呈现,更加易读。3.由于没有setter方法,依赖关系在构造时由容器一次性设定,因此组件在被创建之后即处于相对“不变”的稳定状态,无需担心上层代码在调用过程中执行setter方法对组件依赖关系产生破坏,特别是对于Singleton模式的组件而言,这可能对整个系统产生重大的影响。4.同样,由于关联关系仅在构造函数中表达,只有组件创建者需要关心组件内部的依赖关系。对调用者而言,组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息,也为系统的层次清晰性提供了保证。5.通过构造子注入,意味着我们可以在构造函数中决定依赖关系的注入顺序,对于一个大量依赖外部服务的组件而言,依赖关系的获得顺序可能非常重要,比如某个依赖关系注入的先决条件是组件的DataSource及相关资源已经被设定。BeanFactory简介:BeanFactory,顾名思义,负责创建并维护Bean实例。BeanFactory负责根据配置文件创建Bean实例,可以配置的项目有:1.Bean属性值及依赖关系(对其他Bean的引用)2.Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)3.Bean初始化和销毁方法4.Bean的依赖关系例子:beansdescriptionSpringBeanConfigurationSample/descriptionbeanid=TheAction⑴class=net.xiaxin.spring.qs.UpperAction⑵singleton=true⑶init-method=init⑷destroy-method=cleanup⑸depends-on=ActionManager⑹propertyname=messagevalueHeLLo/value⑺/propertypropertyname=descnull//propertypropertyname=dataSourcereflocal=dataSource/⑻/property/beanbeanid=dataSourceclass=org.springframework.jndi.JndiObjectFactoryBeanpropertyname=jndiNamevaluejava:comp/env/jdbc/sample/value/property/beanSpringFrameWorkDeveloper’sGuideVersion0.6October8,2004Somanyopensourceprojects.WhynotOpenyourDocuments?/beans配置文件详解:⑴idJavaBean在BeanFactory中的唯一标识,代码中通过BeanFactory获取JavaBean实例时需以此作为索引名称。⑵classJavaBean类名⑶singleton指定此JavaBean是否采用单例(Singleton)模式,如果设为“true”,则在BeanFactory作用范围内,只维护此JavaBean的一个实例,代码通过BeanFactory获得此JavaBean实例的引用。反之,如果设为“false”,则通过BeanFactory获取此JavaBean实例时,BeanFactory每次都将创建一个新的实例返回。⑷init-method初始化方法,此方法将在BeanFactory创建JavaBean实例之后,在向应用层返回引用之前执行。一般用于一些资源的初始化工作。⑸destroy-method销毁方法。此方法将在BeanFactory销毁的时候执行,一般用于资源释放。⑹depends-onBean依赖关系。一般情况下无需设定。Spring会根据情况组织各个依赖关系的构建工作(这里示例中的depends-on属性非必须)。只有某些特殊情况下,如JavaBean中的某些静态变量需要进行初始化(这是一种BadSmell,应该在设计上应该避免)。通过depends-on指定其依赖关系可保证在此Bean加载之前,首先对depends-on所指定的资源进行加载。⑺value通过value/节点可指定属性值。BeanFactory将自动根据JavaBean对应的属性类型加以匹配。下面的”desc”属性提供了一个null值的设定示例。注意value/value代表一个空字符串,如果需要将属性值设定为null,必须使用null/节点。⑻ref指定了属性对BeanFactory中其他Bean的引用关系。示例中,TheAction的dataSource属性引用了id为dataSource的Bean。BeanFactory将在运行期创建dataSourcebean实例,并将其引用传入TheActionBean的dataSource属性。代码调用实例:InputStreamis=newFileInputStream(bean.xml);XmlBeanFactoryfactory=newXmlBeanFactory(is);Actionaction=(Action)factory.getBean(TheAction);action.method…..;谢谢!