Spring Framework 5.2.4.RELEASE 核心技术1.2翻译

原文连接spring framework

1.2 容器简介

本章节中org.springframework.context.ApplicationContext接口做为Spring IoC的容器,它的责任是实例化,配置和组装bean。容器是通过读取配置元数据,决定对哪些对象的进行实例化,配置和组合。这些配置元数据,有XML文件,注解,和JAVA代码三种形式。配置元数据可以用来展示你的应用程序的组成对象,以及这些对象之间复杂的关系。

Spring提供了几个ApplicationContext接口的实现类。在单个应用中,通常会创建一个ClassPathXmlApplicationContext或者FileSystemXmlApplicationContext的实例。XML是定义配置元数据的传统格式,你可以指定容器使用JAVA注解或者代码作为元数据格式,仅需要提供少量的XML配置,用来声明支持这些额外的元数据格式。

在大多数应用场景中,用户代码不需要显示的实例化一个或者多个Spring IoC容器。举个例子,在web应用场景中,一个应用通常只需要在web.xml模板文件中,写8行左右的配置。(参考 Convenient ApplicationContext Instantiation for Web Applications),如果你用了Spring Tool Suite(一个Eclipse提供的开发环境)你只用通过点击几下鼠标或者键盘就可以轻松的创建模板配置。

下面的示意图是Spring如何工作的一个高级展示。你应用中的类和配置元数据组合在一起,因此在ApplicationContext被创建和实例化后,你就拥有了一个完整配置过的,可以执行的系统或者应用。
Alt
图片1: spring container

1.2.1 配置元数据

正如上面图片所示,Spring IoC 容器消费了配置元数据表。配置元数据是应用开发者告诉Spring容器,该如何实例化,配置和组装应用内的对象。

配置元数据传统上是一种简单和直观的XML格式,这章中我们主要用XML格式来阐述Spring IoC 容器的主要概念和特性。

配置元数据不是只有XML这一种格式。Spring IoC容器本身写配置文件的时候,已经不再使用XML这种形式了。现在,很多开发者在开发Spring应用的时候,会选择基于Java代码的元数据配置方式。

如果想了解其他Spring容器的元数据配置格式,可以参考:

  • 基于注解的配置:Spring 2.5引入了基于注解配置的元数据格式。
  • 基于Java代码的配置:从Spring3.0开始,Spring JavaConfig工程提供了很多功能,逐步变成了Spring Framework核心的一部分。因此,你可以使用JAVA代码而不是XML文件,在应你的用程序的外部定义bean。为了使用这些新的特性,可以看 @Configuration, @Bean, @Import, and @DependsOn 注解。

Spring配置由容器管理的beans组成,这些beans至少一个,通常会是多个。基于XML的配置元数据,是通过<bean/>标签来配置bean元素的,<bean/>标签嵌套在顶级标签为<beans/>的内部。而基于JAVA的元数据配置格式,通常在@Configuration类中用@Bean-注解来进行配置。

生成与这些Bean定义一致的对象,这些对象是你应用的组成部分。通常,你定义服务层的对象,数据访问层对象(DAOs),表现层对象例如Structs Action实例,底层对象例如 Hibernate SessionFactories, JMS Queues等等。但是,容器一般不会配置细粒度的域对象,因为通常是由DAOs和业务逻辑去创建和加载域对象的。不过,你可以使用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中没有id被引用的内容。可以参考Dependencies获取更多信息。

1.2.2 实例化一个容器

ApplicationContext构造函数所用的配置文件地址是一些资源字符串,容器可以从各种各样的外部资源中加载配置元数据,例如当前文件系统,JAVA CLASSPATH等等。

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

当你了解了Spring IoC容器,你可能想知道Spring的资源提取机制,文件地址是按URI语法定义的,Spring提供了一个简单机制去读取该地址的输入流。特别是,Application Contexts and Resource Paths 中介绍了,Resource路径被用于去构造应用的上下文。

下面的例子展示了服务层对象(services.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>

下面的例子展示了接入层配置文件daos.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类和两个数据接入对象组成的,这两个数据接入对象对应的类分别是JpaAccountDao和JpaItemDao。(基于JPA 对象关系映射标准)。property name标签指的是JavaBean属性的名字,ref标签指的是其他bean定义的名字。id和ref关键字之间的关联,是协作对象之间依赖的表示。想了解更多对象依赖,参考Dependencies

基于XML的组合型配置元数据

组合配置对于跨多个XML文件的bean定义很有作用。通常,每个独立的XML配置文件,代表你架构中的一个逻辑层或者一个模块。

你可以使用应用上下文构造器读取所有的xml文件,加载其中的bean定义。上个章节中提到的如何读取多个资源地址。另外,你还可以通过用一个或者多个< import/>标签去引入其他文件,从而加载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>

在上面的例子中,可以从这三个文件 (services.xml, messageSource.xml, themeSource.xml)中加载他们的bean定义。import文件的路径是以bean定义文件的路径为基准路径,所以services.xml一定和该文件在同一个路径下或者在同一个classpath中,而messageSource.xml 和 themeSource.xml 一定在基准路径的resources文件夹下。正如你所见的,反斜杠会被忽略了。由于给定的路径是相对路径,最好不要使用反斜杠。这些能被引入的文件,顶级标签为<beans/>,必须是一个遵守遵守Spring约束的,有效的XML的bean定义。

有可能引入文件在当前路径的上一级,使用"…/"符号读取,但是不推荐这么做。这样做会导致依赖文件位于当前应用的外部。尤其要注意,classpath URLs(例如classpath:…/services.xml)不推荐使用这种引用, 运行的程序会选择当前的路径作为root路径,然后找它的上一级路径。Classpath配置的改变可能导致选择一个不同的,不正确的文件夹。

你可以使用绝对路径来代替相对路径,例如file:C:/config/services.xml或者classpath:/config/services.xml。不过,你需要知道你将应用的配置和这个特定的绝对路径耦合在一起。更推荐的是用间接手段使用绝对路径,例如使用“${…​}”占位符,他可以在系统运行中解析JVM的系统属性。

命名空间本身提供的引入文件的特性。Spring提供了一些XML命名空间,它们相对于普通bean定义进一步的配置,例如context和util命名空间。

The Groovy Bean Definition DSL

Spring’s Groovy Bean Definition DSL(领域特征语言)来自于Grails框架,它可以在外部配置元数据,bean定义。通常,这些配置存在以".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定义文件格式,甚至可以支持XML配置的命名空间。它也支持通过importBeans引入基于XML的Bean定义文件。

1.2.3使用容器

实现ApplicationContext接口的高级工程类,需要支持不同类型beans的注册和他们依赖的beans注册。通过调用方法 T getBean(String name, Class requiredType),你可以获取到bean的实例。

下面的例子展示了,ApplicationContext读取bean定义,获取bean对象。


// 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-aware(它也理解XML bean 定义格式)。下面例子是Groovy的配置

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

GenericApplicationContext是最灵活的方式,可以和不同的配置读取代理进行结合。例如,使用XmlBeanDefinitionReader读取XML文件,如下所示:


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的定义。

你还可以使用getBean去获取你的beans实例。ApplicationContext有少量的其他方法获取beans,但是理想情况下,你的应用不应该使用他们。事实上,你的应用程序代码不应该调用getBean方法, 也不应该依赖于Spring的 APIS。举个例子,Spring集成web框架,会提供许多web框架组件的依赖注入,例如controllers,JSF-managed beans, 你可以通过元数据(例如@autowiring)去声明一个特定对象的依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值