Spring IOC学习笔记

添加评论 15 views 2010年1月6日

最近开始复习Spring,决定拾起之前学的一点Spring知识,并且深入了解这个框架。看了看【Spring Framework 开发参考手册】,觉得讲的还不错,决定先学习这个手册,掌握一些基础的Spring知识。

在Spring中,那些组成应用的主体(backbone)及由Spring IoC容器所管理的对象被称之为bean。简单地讲,bean就是由Spring容器初始化、装配及被管理的对象,除此之外,bean就没有特别之处了(与应用中的其他对象没有什么区别)。而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。

org.springframework.beans.factory.BeanFactory是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。

在Spring中,BeanFactory是IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

Spring为我们提供了许多易用的BeanFactory实现,如:ClassPathResource、XmlBeanFactory、ClassPathXmlApplicationContext,XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
实现方式分别如下:
Resource resource = new FileSystemResource(“beans.xml”);
BeanFactory factory = new XmlBeanFactory(resource);
… 或…

ClassPathResource resource = new ClassPathResource(“beans.xml”);
BeanFactory factory = new XmlBeanFactory(resource);
… 或…

InputStream is = new FileInputStream(“beans.xml”);
BeanFactory factory = new XmlBeanFactory(is);
… 或…

ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {“applicationContext.xml”, “applicationContext-part2.xml”});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) context;

Spring IoC容器将读取配置元数据;并通过它对应用中各个对象进行实例化、配置以及组装。通常情况下我们使用简单直观的XML来作为配置元数据的描述格式。在XML配置元数据中我们可以对那些我们希望通过Spring IoC容器管理的bean进行定义。

Spring支持三种配置元数据格式:XML格式、Java属性文件格式或使用Spring公共API编程实现

基于XML配置元数据

为了加载多个XML文件生成一个ApplicationContext实例,可以将文件路径作为字符串数组传给ApplicationContext构造器。而bean factory将通过调用bean defintion reader从多个文件中读取bean定义。
另外一种方法是使用一个或多个的<import/>元素来从另外一个或多个文件加载bean定义。所有的<import/>元素必须放在<bean/>元素之前以完成bean定义的导入。
根据Spring XML配置文件的Schema(或DTD),被导入文件必须是完全有效的XML bean定义文件,且根节点必须为<beans/> 元素。

多种bean
诚如此前所言,Spring IoC容器将管理一个或多个bean,这些bean将通过配置文件中的bean定义被创建(在XML格式中为<bean/>元素)。

在容器内部,这些bean定义由BeanDefinition 对象来表示,该定义将包含以下信息:

全限定类名:这通常就是已定义bean的实际实现类。如果通过调用static factory方法来实例化bean,而不是使用常规的构造器,那么类名称实际上就是工厂类的类名。
bean行为的定义,即创建模式(prototype还是singleton)、自动装配模式、依赖检查模式、初始化以及销毁方法。这些定义将决定bean在容器中的行为用于创建bean实例的构造器参数及属性值。比如使用bean来定义连接池,可以通过属性或者构造参数指定连接数,以及连接池大小限制等。
bean之间的关系,即协作 (或者称依赖)。

bean定义包括:
class
name
scope
constructor arguments
properties
autowiring mode
dependency checking mode
lazy-initialization mode
initialization method
destruction method

除了通过bean定义来描述要创建的指定bean的属性之外,某些BeanFactory的实现也允许将那些非BeanFactory创建的、已有的用户对象注册到容器中,比如使用DefaultListableBeanFactory的registerSingleton(..) 方法。不过大多数应用还是采用元数据定义为主。

命名bean
bean命名约定
bean的命名采用标准的Java命名约定,即小写字母开头,首字母大写间隔的命名方式。如accountManager、 accountService、userDao及loginController,等等。

对bean采用统一的命名约定将会使配置更加简单易懂。而且在使用Spring AOP时,如果要发通知(advice)给与一组名称相关的bean时,这种简单的命名方式将会令你受益匪浅。
每个bean都有一个或多个id(或称之为标识符或名称,在术语上可以理解成一回事)。这些id在当前IoC容器中必须唯一。如果一个bean有多个id,那么其他的id在本质上将被认为是别名。

当使用基于XML的配置元数据时,将通过id或name属性来指定bean标识符。id属性具有唯一性,而且是一个真正的XML ID属性,因此其他xml元素在引用该id时,可以利用XML解析器的验证功能。通常情况下最好为bean指定一个id。尽管XML规范规定了XML ID命名的有效字符,但是bean标识符的定义不受该限制,因为除了使用指定的XML字符来作为id,还可以为bean指定别名,要实现这一点可以在name属性中使用逗号、冒号或者空格将多个id分隔。

值得注意的是,为一个bean提供一个name并不是必须的,如果没有指定,那么容器将为其生成一个惟一的name。对于不指定name属性的原因我们会在后面介绍(比如内部bean就不需要)。

在XML配置文件中,可用单独的<alias/> 元素来完成bean别名的定义。如:
<alias name=”fromName” alias=”toName”/>

实例化bean
用构造器来实例化
当采用构造器来创建bean实例时,Spring对class并没有特殊的要求,我们通常使用的class都适用。也就是说,被创建的类并不需要实现任何特定的接口,或以特定的方式编码,只要指定bean的class属性即可。不过根据所采用的IoC类型,class可能需要一个默认的空构造器。

使用 静态工厂方法实例化
当采用静态工厂方法创建bean时,除了需要指定class属性外,还需要通过factory-method属性来指定创建bean实例的工厂方法。Spring将调用此方法(其可选参数接下来介绍)返回实例对象,就此而言,跟通过普通构造器创建类实例没什么两样。

下面的bean定义展示了如何通过工厂方法来创建bean实例。注意,此定义并未指定返回对象的类型,仅指定该类包含的工厂方法。在此例中, createInstance()必须是一个static方法。

<bean id=”exampleBean” factory-method=”createInstance”/>

使用实例工厂方法实例化
用来进行实例化的实例工厂方法位于另外一个已有的bean中,容器将调用该bean的工厂方法来创建一个新的bean实例。
为使用此机制,class属性必须为空,而factory-bean属性必须指定为当前(或其祖先)容器中包含工厂方法的bean的名称,而该工厂bean的工厂方法本身必须通过factory-method属性来设定。

使用容器
从本质上讲,BeanFactory仅仅只是一个维护bean定义以及相互依赖关系的高级工厂接口。通过BeanFactory我们可以访问bean定义。
BeanFactory提供的方法极其简单。它仅提供了六种方法供客户代码调用:
boolean containsBean(String):如果BeanFactory包含给定名称的bean定义(或bean实例),则返回true

Object getBean(String)
:返回以给定名字注册的bean实例。根据bean的配置情况,如果为singleton模式将返回一个共享的实例,否则将返回一个新建的实例。如果没有找到指定的bean,该方法可能会抛出BeansException异常(实际上将抛出NoSuchBeanDefinitionException异常),在对bean进行实例化和预处理时也可能抛出异常


Object getBean(String, Class)
:返回以给定名称注册的bean实例,并转换为给定class类型的实例,如果转换失败,相应的异常

(BeanNotOfRequiredTypeException)将被抛出。上面的getBean(String)方法也适用该规则。

Class getType(String name):返回给定名称的bean的Class。如果没有找到指定的bean实例,则抛出NoSuchBeanDefinitionException异常。

boolean isSingleton(String):判断给定名称的bean定义(或bean实例)是否为singleton模式(singleton将在bean的作用域中讨论),如果bean没找到,则抛出NoSuchBeanDefinitionException异常。

String[] getAliases(String):返回给定bean名称的所有别名。

  1. 还没有评论.想坐沙发?
  1. 还没有 trackbacks
订阅评论