文档是对照spring官方文档进行翻译,都是本人亲自翻译,内容逐字逐句的进行推敲,不同与翻译器的整篇翻译(现有的多数中文文档都是靠翻译器整篇翻译,有很多内容并不能准确表达),应该是目前最好的官方中文文档。

翻译不易,转载请标明出处,尊重原创,从你我做起。

目录

 

1.2 Container Overview

1.2.1 Configuration Metadata

1.2.2 Instantiating a Container

Composing XML-based Configuration Metadata

The Groovy Bean Definition DSL

1.2.3 Using the Container

 


1.2 Container Overview

org.springframework.context.ApplicationContext 接口代表 Spring IoC 容器,并负责实例化,配置和组装Bean。容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。配置元数据以 XML,Java 注解或 Java 代码来描述。它使您能够表达组成应用程序的对象以及这些对象之间的丰富相互依赖关系。

Spring 提供了 ApplicationContext 接口的几种实现。在独立应用程序中,通常创建ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的实例。尽管 XML 是定义 配置元数据的传统格式,但是您可以通过提供少量 XML 配置来声明性地启用对这些其他元数据格式 的支持,从而指示容器将 Java注释或代码用作元数据格式。

在大多数应用场景中,不需要实例化用户代码即可实例化一个 Spring IoC 容器的一个或多个实例。 例如,在 Web 应用程序场景中,应用程序 web.xml 文件中的简单八行(大约)样板Web描述XML 通常就足够了(请参阅Web 应用程序的便捷 ApplicationContext 实例化)。如果使用Spring工具套件(基于 Eclipse 的开发环境),则只需单击几次鼠标或击键即可轻松创建此样板配置。

下图显示了 Spring 的工作原理的高级视图。您的应用程序类与配置元数据结合在一起,以便在创建 和初始化 ApplicationContext 之后,您将具有完全配置且可执行的系统或应用程序。

Spring Statemachine 中文文档 spring官方文档中文pdf_元数据

图 1. Spring IoC 容器

1.2.1 Configuration Metadata

如上图所示,Spring IoC 容器使用一种形式的配置元数据。此配置元数据表示您作为应用程序开发 人员如何告诉 Spring 容器实例化,配置和组装应用程序中的对象。

传统上,配置元数据以简单直观的 XML 格式提供,这是本章大部分内容用来传达 Spring IoC 容器 的关键概念和功能的内容。

基于 XML 的元数据不是配置元数据的唯一允许形式。 Spring IoC 容器本身与实际写入此配 置元数据的格式完全脱钩。如今,许多开发人员为自己的 Spring 应用程序选择Java-based configuration。

有关在 Spring 容器中使用其他形式的元数据的信息,请参见:

  • Annotation-based configuration:spring2.5引入了基于注释的配置元数据的支持
  • Annotation-based configuration:从Spring3.0开始,SpringConfig项目提供的很多功能都成为了Spring Framework的核心内容的一部分。因此,您可以使用Java而不是XML文件在应用程序类的外部定义bean。要使用这些新特性,请参阅@Configuration@Bean@Import@DependsOn注释

Spring配置由容器必须管理的至少一个bean定义(通常是多个bean定义)组成。XML是通过在顶级元素中的元素来配置元数据。Java是通过在一个@Configuration类中标记@Bean来配置元数据。

这些 bean 定义对应于组成应用程序的实际对象。通常,您定义服务层对象,数据访问对象(DAO),表示对象(例如 Struts Action 实例),基础结构对象(例如 Hibernate SessionFactories,JMS Queues 等)。通常,不会在容器中配置细粒度的域对象,因为 DAO 和业务逻辑通常负责创建和加载域对象。但是,您可以使用 Spring 与 AspectJ 的集成来配置在 IoC 容器的控制范围之外创建的对象。参考Using AspectJ to dependency-inject domain objects with Spring

以下示例显示了基于 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
        https://www.springframework.org/schema/beans/spring-beans.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>
  • Id属性是标识bean的字符串
  • class属性定义的是bean的类型,使用全名限定的类名

id 属性的值是被协作对象用来引用的。在此示例中未显示用于引用协作对象的 XML。有关更多信息,请参见 Dependencies

1.2.2 Instantiating a Container

通过给ApplicationContext构造器提供一个资源位置的字符串来使得容器从外部的资源文件加载配置化的元数据。例如本地文件系统,类路径或者其他。

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

了解了 Spring 的 IoC 容器之后,您可能想了解更多有关 Spring 的 Resource 抽象(如Resources中所述),该抽象为从 URI 语法中定义的位置读取 InputStream 提供了一种方便的机制。特别是, Resource 路径用于构建应用程序上下文,如Application Contexts and Resource Pathss所述。

下面是service.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- services -->

    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

下面是dao.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao"
        class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

在上面的示例中,服务层是由一个PetStoreServiceImpl和两个数据访问类型的对象JpaAccountDaoJpaItemDao组成(是基于标准的JPA面向对象映射的)。那个property name元素引用JavaBean 属性的名称,而 ref 元素引用另一个 bean 定义的名称。id 和 ref 元素之间的这种 联系表达了协作对象之间的依赖性。有关配置对象的依赖项的详细信息,请参见:Dependencies

Composing XML-based Configuration Metadata

跨越多个xml文件来定义bean是很有用的。通常一个单独xml配置文件代表一个逻辑层或者是你架构中的一个模块。

你可以通过应用上下文的构造器从这些所有的xml片段中加载对bean的定义。这个构造器可以有多个Resource路径字符串,就像前面案例所示。或者多次使用元素来从别的文件加载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定义都是从service.xml、messageSource.xml和themeSource.xml三个文件。所有的位置路径都是相对于引进的那个文件,所以service.xml必须于引入的文件相同目录或者位置路径一样。而messageSource.xml和messageSource.xml必须是位于引入文件目录下的resouce目录下。正如你所看见的,前面的"/"符号被省略了。然而,考虑到这些路径是相对的,最好完全不使用斜杠。根据Spring模式,被导入的文件的内容,包括顶层的元素,必须是有效的XML bean定义。

可以使用相对的".. "来引用父目录中的文件,但不建议这样做。/”路径。这样做会在当前应用程序之外的文件上创建一个依赖项。特别地,不建议对classpath: url(例如,classpath:../services.xml)引用此引用,在这种情况下,运行时解析过程会选择“最近的”类路径根,然后查看它的父目录。类路径配置的更改可能会导致选择一个不同的、错误的目录。

您总是可以使用完全限定的资源位置而不是相对路径:例如,file:C:/config/services.xml或classpath:/config/services.xml。但是,请注意您是将应用程序的配置耦合到特定的绝对位置。一般来说,最好为这样的绝对位置保留一个间导性——例如,通过“${…}”占位符在运行时根据JVM系统属性解析占位符。

命名空间本身提供导入指令特性。除了纯bean定义之外,Spring提供的XML名称空间还提供了更多的配置特性—例如,contextutil名称空间。

The Groovy Bean Definition DSL

作为外部化配置元数据的进一步示例,bean定义也可以用Spring的Groovy bean定义DSL表示,即Grails框架所知的DSL。通常,这样的配置存在于'。groovy文件的结构如下例所示:

beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
        dataSource = dataSource
    }
    myService(MyService) {
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}

这个配置格式大部分与xml的bean定义相同,甚至可以支持Spring的xml配置命名空间。它同样支持使用improtBeans的命令来引入xml的bean 定义元数据。

1.2.3 Using the Container

ApplicationContext是一个具有对所注册的不同bean和它们所依赖的bean更好维护能力的先进的工厂的接口。使用T getBean(String name, Class<T> requiredType)方法来检索你的beans。

ApplicationContext允许你读取和访问bean definitions,想下面这样:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

通过Groovy的配置,启动会显得比较小巧。它有一个不同的上下文实现类,它支持groovy(但也理解XML bean定义)。下面的例子展示了Groovy的配置:

ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

最灵活的变体是GenericApplicationContext与阅读器委托的结合——例如,针对XML文件的XmlBeanDefinitionReader,如下面的例子所示:

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();

你也可以使用GroovyBeanDefinitionReader来读取Groovy文件,例如下面:

GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();

你可以在同一个ApplicationContext中混合使用阅读器委托,来从不同的资源位置读取bean definition。

你可以使用getBean()方法获取你的bean实例,ApplicationContext中有很多方法获取bean,但是聪明的话,最好不要使用它们。实际上,您的应用程序代码根本不应该调用getBean()方法,因此根本不依赖于Spring api。例如Spring与web框架整合提供了通过依赖注入web框架组件的变体,比方说Controller和Jsf-manager。让你可以在一个bean上通过元数据(例如自动装配注释@Autowried)来声明依赖。