Spring 开发指南笔记<o:p></o:p>
<o:p></o:p>
Spring 基础语义<o:p></o:p>
何谓控制反转(IoC = Inversion of Control),何谓依赖注入(DI = Dependency Injection)?概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。<o:p></o:p>
相对IoC 而言,“依赖注入”的确更加准确的描述了这种古老而又时兴的设计理念。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。<o:p></o:p>
所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。讲的通俗点,就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进行设定。<o:p></o:p>
<o:p></o:p>
依赖注入的几种实现类型<o:p></o:p>
Ø Type1 接口注入<o:p></o:p>
我们常常借助接口来将调用者与实现者分离。如:<o:p></o:p>
public class ClassA {<o:p></o:p>
private InterfaceB clzB;<o:p></o:p>
public doSomething() {<o:p></o:p>
Ojbect obj =<o:p></o:p>
Class.forName(Config.BImplementation).newInstance();<o:p></o:p>
clzB = (InterfaceB)obj;<o:p></o:p>
clzB.doIt()<o:p></o:p>
}<o:p></o:p>
……<o:p></o:p>
}<o:p></o:p>
上面的代码中,ClassA依赖于InterfaceB的实现,如何获得InterfaceB实现类的实例?传统的方法是在代码中创建InterfaceB实现类的实例,并将起赋予clzB。<o:p></o:p>
而这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码,我们根据预先在配置文件中设定的实现类的类名(Config.BImplementation),动态加载实现类,并通过InterfaceB强制转型后为ClassA所用。这就是接口注入的一个最原始的雏形。<o:p></o:p>
<o:p></o:p>
而对于一个Type1型IOC容器而言,加载接口实现并创建其实例的工作由容器完成。<o:p></o:p>
如下面这个类:<o:p></o:p>
public class ClassA {<o:p></o:p>
private InterfaceB clzB;<o:p></o:p>
public Object doSomething(InterfaceB b) {<o:p></o:p>
clzB = b;<o:p></o:p>
return clzB.doIt();<o:p></o:p>
}<o:p></o:p>
……<o:p></o:p>
}<o:p></o:p>
在运行期,InterfaceB实例将由容器提供。<o:p></o:p>
<o:p></o:p>
Ø Type2 设值注入 (setter)<o:p></o:p>
在各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得力于Spring框架的影响)。在笔者看来,基于设置模式的依赖注入机制更加直观、也更加自然。Quick Start中的示例,就是典型的设置注入,即通过类的setter方法完成依赖关系的设置。<o:p></o:p>
Ø Type3 构造子注入<o:p></o:p>
构造子注入,即通过构造函数完成依赖关系的设定,如:<o:p></o:p>
public class DIByConstructor {<o:p></o:p>
private final DataSource dataSource;<o:p></o:p>
private final String message;<o:p></o:p>
public DIByConstructor(DataSource ds, String msg) {<o:p></o:p>
this.dataSource = ds;<o:p></o:p>
this.message = msg;<o:p></o:p>
}<o:p></o:p>
……<o:p></o:p>
}<o:p></o:p>
可以看到,在Type3类型的依赖注入机制中,依赖关系是通过类构造函数建立,容器通过调用类的构造方法,将其所需的依赖关系注入其中。<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
Spring Bean封装机制<o:p></o:p>
Spring 从核心而言,是一个DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代码中涉及Spring专有类,即可将其纳入Spring容器进行管理。<o:p></o:p>
作为对比,EJB则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付出极大的代价。为了避免这种情况,实现无侵入性的目标。Spring 大量引入了Java 的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。<o:p></o:p>
org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper和BeanFactory类。这两个类从技术角度而言并不复杂,但对于Spring 框架而言,却是关键所在,如果有时间,建议对其源码进行研读,必有所获。<o:p></o:p>
所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。讲的通俗点,就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进行设定。<o:p></o:p>
<o:p></o:p>
Bean相关包<o:p></o:p>
Spring 的核心是org.springframework.beans 包,为使用JavaBeans 技术、按名检索对象及管理对象间的关系而设计。beans包及其子包提供的功能为使用JavaBeans 技术的项目指定了一个基础设施。<o:p></o:p>
关于beans 包,有三个重要的概念。首先,它提供了设置/读取Javabeans 属性功能的BeanWrapper接口。第二个重要概念是Bean 工厂。BeanFactory 是一个泛化工厂,具有实例化对象和管理不同对象间关系的能力。BeanFactory 可以管理几种不同类型的bean,并且支持串行化及其他生命周期方法。BeanFactory 是按照bean 定义(BeanDefinition)来实例化对象的。BeanDefinition,顾名思义,是你对bean 的定义。BeanDefinition 不仅定义了bean 的类结构、实例化的方式,还定义了bean 在运行时的合作者。这是第三个概念。这三个概念( BeanFactory, BeanWrapper and BeanDefinition)将在下文详细讨论。<o:p></o:p>
对于org.springframework.beans 包遵循Sun 公司发布的JavaBeans 标准。所谓“JavaBean”其实就是一个Java 类。不过,它必须拥有默认无参数构造器,并按照既定规则来命名属性——属性prop对应一个设置器setProp(…)和读取器getProp(…)。更多的关于JavaBeans 的信息请查阅Sun 公司网站(java.sun.com/products/javabeans[http://java.sun.com/products/javabeans/]).<o:p></o:p>
<o:p></o:p>
Bean Definitions
Bean definitions 是你的bean 的详细描述。Bean 就是一些提供某些特定功能的普通类,<o:p></o:p>
BeanFactory 接口如何管理你的bean 以及它们是怎样配置的,都是在一个bean definition 中规定的。以下就是bean definition 实际模型,这个模型使得bean definition 能够实例化bean。<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
第一个例子以IoC 类型2(使用设置器)方式使用BeanFactory。下面是指定bean definition<o:p></o:p>
的部分XML 文件片断。你同样可以通过适当的设置器声明找到真正的bean。<o:p></o:p>
<o:p></o:p>
applicationContext.xml片断:<o:p></o:p>
<bean id="exampleBean" class="examples.ExampleBean"><o:p></o:p>
<property name="beanOne"><ref bean="anotherExampleBean"/></property><o:p></o:p>
<property name="beanTwo"><ref bean="yetAnotherBean"/></property><o:p></o:p>
<property name="integerProperty">1</property><o:p></o:p>
</bean><o:p></o:p>
<bean id="anotherExampleBean" class="examples.AnotherBean"/><o:p></o:p>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/><o:p></o:p>
<o:p></o:p>
public class ExampleBean {<o:p></o:p>
private AnotherBean beanOne;<o:p></o:p>
private YetAnotherBean beanTwo;<o:p></o:p>
private int i;<o:p></o:p>
public void setBeanOne(AnotherBean beanOne) {<o:p></o:p>
this.beanOne = beanOne;<o:p></o:p>
public void setBeanTwo(YetAnotherBean beanTwo) {<o:p></o:p>
this.beanTwo = beanTwo;<o:p></o:p>
public void setIntegerProperty(int i) {<o:p></o:p>
this.i = i;<o:p></o:p>
正如你所看到的,声明的设置器在XML 文件中被指定为一个相应的属性。(XML 文件中的属性直接与RootBeanDefinition 中定义的PropertyValues 相联系)。<o:p></o:p>
<o:p></o:p>
客户端与factory 的交互<o:p></o:p>
客户端介面惊人的简单――BeanFactory 接口只有4 个方法与客户端交互:<o:p></o:p>
Ø Object getBean(String):按名返回一个已注册bean 的实例。取决于该bean 在BeanFactory 中的配置,将返回一个共享的唯一的bean 实例或者是一个重新创建的bean 实例。当无法找到bean的定义(此时将引发一个NoSuchBeanDefinitionException 异常)或者在进行实例化和初始化bean 时引发了一个异常,都将引起一个BeansException 异常被抛出。<o:p></o:p>
Ø Object getBean(String,Class): 按名返回一个已注册bean 的实例。这个bean 实例的Class 类型必须和给出的Class 类型参数相匹配,否则相应的异常将会被抛出<o:p></o:p>
(BeanNotOfRequiredTypeException 异常)将会被抛出。此外,这个方法的其他的行为和<o:p></o:p>
getBean(String)方法相同。(请参考getBean(String)方法)<o:p></o:p>
Ø boolean isSingleton(String):按名检测已注册的beandefinition 是被设定为singleton 模式还是prototype 模式。如果给定的beandefinition 没有找到, 则抛出一个异常(NoSuchBeanDefinitionException 异常)<o:p></o:p>
Ø String[] getAliases(String):返回某个已配置bean 的别名(TODO:这意味着什么?)<o:p></o:p>
<o:p></o:p>
BeanFactory 的实现<o:p></o:p>
<o:p></o:p>
在XML 中指定bean 定义(XmlBeanFactory)<o:p></o:p>
BeanFactory 接口的一个实现是XmlBeanFactory 类(位于<o:p></o:p>
org.springframework.beans.factory.xml 包中)。正如它的名字所告诉你的,它为你提供了在XML文件中指定bean 定义的能力。Spring 提供了相应的DTD,使校验bean 定义XML 文件合法性的工作变得简单些。<o:p></o:p>
Spring XML bean 定义文档的根元素是<beans>。<beans>元素可以包含一个或多个bean 定义。我们通常指定每个bean 定义的类和属性。同时,我们也必须指定id――这是bean 的名字,我们将在代码中以这个名字使用这个bean。<o:p></o:p>
我们将使用Jakarta Commons DBCP 项目中的BasicDataSource 类。这个<o:p></o:p>
<v:line id="_x0000_s1026" style="Z-INDEX: 1; POSITION: absolute; flip: x; mso-position-horizontal: absolute; mso-position-vertical: absolute" coordsize="21600,21600" to="198pt,96.8pt" from="135pt,26.6pt"><v:stroke endarrow="block"></v:stroke></v:line>类(和其他很多早已存在的类一样)可以在Spring 轻松地使用,因为它提供了JavaBean 风格的配置方式。此类的实例在销毁前需要调用close 方法。这个方法通过Spring 的“destroy-method”attribute 在BeanFactory 中进行注册,而无需实现任何Spring 接口(否则你就需要实现早前在“生命周期特性”一节中提到的DisposableBean 接口)。<o:p></o:p>
<beans><o:p></o:p>
<bean id="myDataSource"<o:p></o:p>
class="org.apache.commons.dbcp.BasicDataSource"<o:p></o:p>
destroy-method="close"><o:p></o:p>
<!-- results in a setDriverClassName(String) call --><o:p></o:p>
<property name="driverClassName"><o:p></o:p>
<value>com.mysql.jdbc.Driver</value><o:p></o:p>
</property><o:p></o:p>
<property name="url"><o:p></o:p>
<value>jdbc:mysql://localhost:3306/mydb</value><o:p></o:p>
</property><o:p></o:p>
<property name="username"><o:p></o:p>
<value>root</value><o:p></o:p>
</property><o:p></o:p>
</bean><o:p></o:p>
</beans><o:p></o:p>
<o:p></o:p>
就像使用destroy-method attribute 指定一个析构方法,我们可以使用init-method attribute指定一个初始化方法。<o:p></o:p>
<o:p></o:p>
指定多个灵活属性,像list, properties 对象,或者Map 会出现两种可能。下面的例子展示了这种行为:<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
<v:shapetype id="_x0000_t75" coordsize="21600,21600" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id="_x0000_i1025" style="WIDTH: 483pt; HEIGHT: 257.25pt" type="#_x0000_t75"><v:imagedata cropright="4445f" cropleft="10486f" cropbottom="18594f" croptop="11027f" o:title="" src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/01/clip_image002.png"></v:imagedata></v:shape><o:p></o:p>
<v:shape id="_x0000_i1026" style="WIDTH: 483pt; HEIGHT: 250.5pt" type="#_x0000_t75"><v:imagedata cropright="4445f" cropleft="10486f" cropbottom="18265f" croptop="12482f" o:title="" src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/01/clip_image004.png"></v:imagedata></v:shape><o:p></o:p>
<o:p></o:p>
分享到:
相关推荐
spring学习笔记
### Spring学习笔记(精华全记录) #### Spring框架概述 Spring框架源自Rod Johnson的个人项目,最初于2002年末发布。Spring并非一开始就作为一个完整的框架出现,而是从一个项目逐步发展而来。随着项目的成熟,...
### Spring学习笔记知识点详解 #### 一、Spring框架概述 **Spring** 是一个开源的、分层的企业级应用开发框架,旨在简化Java EE应用程序的开发。它的主要目标是提高开发效率,减少耦合度,并提供一种更为简洁的...
Spring学习笔记( spring视频笔记)
这份"Spring学习笔记+学习源码.zip"资源包含了深入学习Spring及其相关技术的知识点,以及实践代码,对提升Spring技能将大有裨益。 首先,我们来详细讨论Spring框架的主要组件和功能: 1. **依赖注入(Dependency ...
### Spring学习笔记:深入理解AOP与Annotation驱动的动态代理 #### 核心知识点解析: 在探讨Spring框架中AOP(面向切面编程)及基于Annotation的动态代理之前,我们首先需要了解AOP的基本概念及其在Spring中的实现...
本资料“Spring学习笔记&源码”是基于网易云课堂黑马程序员的Spring四天精通课程,旨在帮助学习者深入理解和实践Spring框架。 笔记部分可能会涵盖以下内容: 1. **Spring概述**:介绍Spring框架的历史、特点和主要...
Spring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).doc
根据提供的压缩包文件名,我们可以推测这是一个逐步学习Spring的系列笔记。从"Spring_day1"开始,可能涵盖了Spring的基础概念、环境搭建和基本配置。"Spring_day2"可能涉及了依赖注入和AOP的深入讲解。"Spring_day3...
“Java Spring学习笔记”是一份宝贵的资源,专门为想要学习和掌握Java Spring框架的开发者而设计。这份学习笔记提供了详细而系统的教程和实践指南,帮助初学者快速入门,并带领已经有一定经验的开发者深入理解和应用...
### Spring学习笔记知识点详解 #### 一、Spring框架概述 **1.1 什么是Spring** Spring框架是一个开源的轻量级应用框架,主要用于简化企业级应用程序的开发过程。它的核心特性在于提供了一种灵活的方式来组织和...
"尚学堂Spring学习笔记" 本文档记录了尚学堂Spring学习笔记的重要知识点,涵盖了Spring配置文件的设置、普通属性的注入、自定义属性编辑器、公共属性的注入、Spring注解等内容。 一、Spring配置文件的设置 在...
Spring学习笔记
Spring学习笔记2涵盖了Spring框架的核心概念和重要特性,旨在帮助开发者深入理解并熟练掌握Spring的使用。 1. **依赖注入(Dependency Injection, DI)**:这是Spring最核心的设计原则,它允许对象之间的依赖关系在...
在本篇Spring学习笔记中,我们将深入探讨Spring的基本概念,包括bean的配置、依赖注入、IOC容器以及Bean的实例化方式。 首先,Spring中的核心概念是bean。Bean是Spring框架中的基本构建块,它们是被管理的对象,...
这份"Spring学习笔记"涵盖了Spring框架的基础到高级应用,对于想要深入理解并掌握Spring的开发者来说是一份宝贵的资料。 1. **Spring概述**:Spring是一个开源的Java平台,主要设计用于简化企业级应用开发。它提供...
【标题】:“Spring学习笔记0.0.0” 在IT领域,Spring框架是Java开发者广泛使用的轻量级应用框架,它极大地简化了企业级Java应用的开发。这本“Spring学习笔记0.0.0”显然是针对初学者或正在深化Spring技术理解的...