`
suiliangxiang
  • 浏览: 69099 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring容器和bean的基本原理

阅读更多

本文由石头发表于:http://changshi.chen.blog.163.com/blog/static/2542389520077532736199/

 

控制反转: Inversion of Control,IoC

Spring框架所提供的众多功能之所以能成为一个整体正是建立在IoC的基础之上,因此对这一内涵简单、外延丰富的技术我们有必要进行详细的介绍。

org.springframework.beans及org.springframework.context包是Spring IoC容器的基础。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。ApplicationContext是BeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。

简而言之,BeanFactory提供了配制框架及基本功能,而ApplicationContext则增加了更多支持企业核心内容的功能。ApplicationContext完全由BeanFactory扩展而来,因而BeanFactory所具备的能力和行为也适用于ApplicationContext。

容器和bean的基本原理:

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

(Notic:接口选择之惑
在实际应用中,用户有时候不知道到底是选择BeanFactory接口还是ApplicationContext接口。但是通常在构建J2EE应用时,使用ApplicationContext将是更好的选择,因为它不仅提供了BeanFactory的所有特性,同时也允许使用更多的声明方式来得到我们想要的功能。)

(Notice:为什么使用bean?
使用'bean'这个名字而不是'组件'(component) 或'对象'(object)的动机源于Spring框架本身(部分原因则是相对于复杂的EJB而言的)

容器:org.springframework.beans.factory.BeanFactory是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。
在Spring中,BeanFactory是IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。

配置元数据:
Spring IoC容器将读取配置元数据;并通过它对应用中各个对象进行实例化、配置以及组装。通常情况下我们使用简单直观的XML来作为配置元数据的描述格式。在XML配置元数据中我们可以对那些我们希望通过Spring IoC容器管理的bean进行定义。
Note:
到目前为止,基于XML的元数据是最常用到的配置元数据格式。然而,它并不是唯一的描述格式。Spring IoC容器在这一点上是完全开放的。
在本文写作时,Spring支持三种配置元数据格式:XML格式、Java属性文件格式或使用Spring公共API编程实现。由于XML元数据配置格式简单明了,因而本章采用该格式来表达Spring IoC容器的主要理念和特性。
 
在大多数的应用程序中,并不需要用显式的代码去实例化一个或多个的Spring IoC容器实例。例如,在web应用程序中,我们只需要在web.xml中添加(大约)8 行简单的XML描述符即可(参见Section 3.8.4, “ApplicationContext在WEB应用中的实例化”)。(监听器)

多种资源
对IoC容器基本原理的掌握将有利于我们对Chapter 4, 资源中Resource抽象机制的理解。
Spring IoC容器可以通过多种途径来加载配置元数据,比如本地文件系统、Java CLASSPATH等。

bean定义与应用程序中实际使用的对象一一对应。通常情况下bean的定义包括:服务层对象、数据访问层对象(DAO)、类似Struts Action的表示层对象、Hibernate SessionFactory对象、JMS Queue对象等等。项目的复杂程度将决定bean定义的多寡。

以下是一个基于XML的配置元数据的基本结构:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <!-- more bean definitions go here... -->
</beans>

实例化容器
Spring IoC容器的实例化非常简单,如下面的例子:
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
... 或...
ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
... 或...
ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) context;

将XML配置文件分拆成多个部分是非常有用的。为了加载多个XML文件生成一个ApplicationContext实例,可以将文件路径作为字符串数组传给ApplicationContext构造器。而bean factory将通过调用bean defintion reader从多个文件中读取bean定义。
通常情况下,Spring团队倾向于上述做法,因为这样各个配置并不会查觉到它们与其他配置文件的组合。另外一种方法是使用一个或多个的<import/>元素来从另外一个或多个文件加载bean定义。所有的<import/>元素必须放在<bean/>元素之前以完成bean定义的导入。 让我们看个例子:
<beans><import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>
      <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
  </beans>

bean定义:
名称  链接
class  Section 3.2.3.2, “实例化bean”
 
name  Section 3.2.3.1, “命名bean”
 
scope  Section 3.4, “bean的作用域”
 
constructor  arguments Section 3.3.1, “注入依赖”
 
properties   Section 3.3.1, “注入依赖”
 
autowiring   mode Section 3.3.6, “自动装配(autowire)协作者”
 
dependency   checking mode Section 3.3.7, “依赖检查”
 
lazy-initialization mode Section 3.3.5, “延迟初始化bean”
 
initialization method Section 3.5.1, “Lifecycle接口”
 
destruction  method Section 3.5.1, “Lifecycle接口”
 
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就不需要)。

在对bean进行定义时,除了使用id属性来指定名称之外,为了提供多个名称,需要通过alias属性来加以指定。而所有的这些名称都指向同一个bean,在某些情况下提供别名非常有用,比如为了让应用的每一个组件能更容易的对公共组件进行引用。
然而,在定义bean时就指定所有的别名并不是总是恰当的。有时我们期望能在当前位置为那些在别处定义的bean引入别名。在XML配置文件中,可用单独的<alias/> 元素来完成bean别名的定义。如:
<alias name="fromName" alias="toName"/>

实例化bean
就Spring IoC容器而言,bean定义基本上描述了创建一个或多个实际bean对象的内容。当需要的时候,容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数据使用反射机制来创建一个实际的对象。因此这一节将讲解如何告知Spring IoC容器我们将要实例化的对象的类型以及如何实例化对象。

当采用XML描述配置元数据时,将通过<bean/>元素的class属性来指定实例化对象的类型。class 属性 (对应BeanDefinition实例的Class属性)通常是必须的(不过也有两种例外的情形,见Section 3.2.3.2.3, “使用实例工厂方法实例化”和Section 3.6, “bean定义的继承”)。

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

此外,IoC容器不仅限于管理JavaBean,它可以管理任意的类。不过大多数使用Spring的人喜欢使用实际的JavaBean(具有默认的(无参)构造器及setter和getter方法),但在容器中使用非bean形式(non-bean style)的类也是可以的。比如遗留系统中的连接池,很显然它与JavaBean规范不符,但Spring也能管理它。

使用 静态工厂方法实例化
当采用静态工厂方法创建bean时,除了需要指定class属性外,还需要通过factory-method属性来指定创建bean实例的工厂方法。Spring将调用此方法(其可选参数接下来介绍)返回实例对象,就此而言,跟通过普通构造器创建类实例没什么两样。
下面的bean定义展示了如何通过工厂方法来创建bean实例。注意,此定义并未指定返回对象的类型,仅指定该类包含的工厂方法。在此例中, createInstance()必须是一个static方法。
<bean id="exampleBean"
      class="examples.ExampleBean2"
      factory-method="createInstance"/>

从本质上讲,BeanFactory仅仅只是一个维护bean定义以及相互依赖关系的高级工厂接口。通过BeanFactory我们可以访问bean定义。下面的例子创建了一个bean工厂,此工厂将从xml文件中读取bean定义:

InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
基本上就这些了,接着使用getBean(String)方法就可以取得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名称的所有别名。

 

分享到:
评论

相关推荐

    第2章 容器和bean的基本原理1

    【Spring框架技术——容器和bean的基本原理】 Spring框架的核心特性之一是依赖注入(Dependency Injection,简称DI),也称为控制反转(Inversion of Control,简称IoC)。这一特性改变了传统组件调用的方式,使得...

    springIoc实现原理

    在传统的软件设计中,对象的创建和依赖关系的维护通常由代码自身来完成,而在Spring Ioc中,这些控制权被反转给了Spring容器,使得对象的生命周期管理和依赖注入变得更为灵活和可扩展。 **一、控制反转(IoC)概念*...

    Spring简单模拟Spring容器

    标题中的“Spring简单模拟Spring容器”意味着我们将探讨Spring框架的核心特性——IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入),以及如何通过编程方式模拟Spring容器的工作原理。...

    简单Spring容器实现

    本主题将深入探讨“简单Spring容器实现”,基于提供的标签“源码”和“工具”,我们将聚焦于Spring容器的原理及其简易实现。下面,我们先来理解Spring容器的核心概念,然后逐步探索其内部机制,并通过一个名为...

    spring ioc和aop原理流程图(详细)

    Spring容器负责管理Bean的生命周期,并根据Bean之间的依赖关系进行实例化和装配。依赖可以通过属性注入、构造函数注入或方法注入等方式实现。 4. **Bean的作用域**:Spring提供了多种Bean的作用域,如单例...

    Spring2.5视频教程_编码剖析Spring管理Bean的原理

    IoC使得应用程序的控制权从代码本身转移到Spring容器,而DI则负责在运行时将Bean的依赖关系注入到它们的实例中,从而实现解耦。 首先,讲解了Spring配置Bean的基本方式,这通常通过XML配置文件实现。在XML文件中,...

    Spring容器的通俗理解及简单写法

    通过理解并掌握Spring容器的工作原理,开发者可以更有效地利用Spring框架,提高代码的可测试性、可维护性和可扩展性。在实践中,Spring的IoC容器可以帮助我们编写出更加灵活和模块化的代码,从而提升整个应用的质量...

    spring创建bean简单示例

    Spring提供了多种注解,如`@Component`、`@Service`、`@Repository`和`@Controller`,它们可以用来标记Bean类,自动注册到Spring容器。同时,使用`@Autowired`注解可以完成依赖注入。 ```java @Service public ...

    spring IOC反射装载bean

    首先,Spring容器通过读取XML配置文件来获取Bean的定义。这些配置文件通常以`beans.xml`的形式存在,其中包含了Bean的名称、类名、依赖关系和其他属性。例如,一个简单的Bean定义可能如下所示: ```xml &lt;bean id=...

    Spring bean 管理

    Spring框架是Java企业级应用开发的事实标准,它通过依赖注入(DI)和面向切面编程(AOP)来...需要注意的是,无论是哪种方式,理解Spring Bean管理的原理和生命周期,对于开发高质量的Java企业级应用都是必不可少的。

    spring自动扫描和管理Bean的示例

    在Spring框架中,自动扫描和管理Bean是一种便捷的方式,它允许开发者无需显式地在配置文件中声明每个Bean,而是让Spring容器自动发现并管理应用中的组件。这一特性极大地简化了Spring应用的配置,提高了开发效率。...

    Spring实现原理及IoC容器的优点

    然后,你可以使用注解如@Controller、@Service、@Repository和@Service来标记你的类,这些注解将被Spring容器自动扫描并管理。 在Web层,可以使用Spring MVC框架,通过定义DispatcherServlet和Controller来处理HTTP...

    对Spring中注解怎么实现的一些基本原理

    在Spring中,常见的注解如`@Autowired`、`@Component`、`@Service`、`@Repository`和`@Controller`等,用于标记类、方法或字段,以便Spring容器进行自动配置和管理。 **注解的处理过程:** 1. **扫描和发现**:...

    Spring Bean 加载顺序 .

    在Spring框架中,Bean的加载顺序是理解Spring IoC(Inversion of Control,控制反转)容器工作原理的关键部分。这个过程涉及到Bean定义的解析、实例化、初始化等多个步骤。让我们详细探讨Spring Bean加载顺序的各个...

    编码剖析Spring装配基本属性的原理

    Spring容器负责创建对象、管理和装配它们的依赖。通过XML或注解,我们可以声明依赖关系,Spring会自动处理这些关系,确保对象在正确的时间被正确地初始化。 5. Profiles: Spring支持多环境配置,通过`@Profile`...

    spring bean的生命周期测试代码

    4. **容器回调**:在Bean初始化之后,Spring容器可能会调用自己的回调方法,如`BeanPostProcessor`接口实现的`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`方法,允许自定义逻辑进一步...

    Spring的bean生命周期

    Bean生命周期的理解对于优化应用性能和理解Spring内部工作原理至关重要。这里我们将深入探讨Spring的Bean生命周期、容器周期以及工厂周期。 首先,让我们从Bean生命周期开始。在Spring中,Bean的生命周期包括以下几...

    Spring技术内幕:深入解析Spring架构与设计原理[汇编].pdf

    * IoC容器(Inversion of Control):Spring的核心是IoC容器,IoC容器负责管理Bean的生命周期和依赖关系。 * 依赖注入(Dependency Injection): Spring使用依赖注入来解耦合应用程序中的组件,提高系统的灵活性...

    自己实现的简单Spring 容器

    首先,我们要知道Spring容器的主要功能是管理和装配Bean。在Spring中,Bean通常代表应用程序中的业务对象或者服务组件。容器通过读取配置文件(如XML、Java注解或Java配置类)来了解这些Bean的定义,包括它们的类型...

    【Spring】总结Spring整合Mybatis的底层原理实现步骤

    本文主要探讨Spring整合Mybatis的底层原理和实现步骤,结合鲁班学院公开课笔记,深入理解这一过程。 首先,Dao层是数据访问层,它提供了Service层调用的接口,有时甚至可以作为一个独立的项目。在Spring整合Mybatis...

Global site tag (gtag.js) - Google Analytics