7.2.2 实例化容器

实例化Spring的IoC容器很简单。提供给ApplicationContext构造方法的一个或多个路径是表示实际资源的字符串,通过路径容器能从各种外部资源(比如本地文件系统)、Java的CLASSPATH等处加载配置元数据。

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

在了解了Spring的IoC容器之后,您可能想知道更多关于Spring的Resource抽象的知识,如第8章资源中所述,它提供了一个方便的机制用于从用URI语法定义的地址读取InputStream。尤其如第8.7节“应用程序上下文和资源路径”中所述,Resource路径用于构建应用程序的上下文。

下面的例子展示了service层对象的配置文件(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
        http://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
        http://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>

在前面的例子中,service层由PetStoreServiceImpl类和两个数据访问对象组成,数据访问对象一个是JpaAccountDao类类型,一个是JpaItemDao类类型(基于JPA对象/关系映射标准)。property name元素是指JavaBean属性的名称,ref元素引用另一个bean定义的名字。idref元素之间的这种联系表示了协作对象之间的依赖关系。关于配置对象的依赖关系的细节,请参阅依赖

编写基于XML的配置元数据

让bean定义跨越多个XML文件非常有用。通常,每个单独的XML配置文件代表架构中一个逻辑层或模块。

您可以使用应用程序上下文的构造方法从所有这些XML片段加载bean的定义。就像前面的小节展示的,该构造方法可以接受多个Resource地址。或者,使用一个或多个<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>

在前面的例子中,外部的bean定义从三个文件中加载:services.xmlmessageSource.xmlthemeSource.xml。导入它们的定义文件中使用的地址都是相对路径,所以services.xml必须和导入它的文件在同一目录下或着在类路径中,而messageSource.xmlthemeSource.xml必须在下一级的resources目录中。正如您所看到的,开头的斜线被忽略掉了,但是考虑到这些路径都是相对的,所以最好根本不使用斜线。被导入文件的内容,包括顶层的<beans/>元素,都必须是依据Spring Schema有效的bean定义XML。

使用相对的"../"路径来引用上层目录中的文件是可以的,但是不建议。这样做会创建对当前应用程序之外的文件的依赖。特别是,不建议对"classpath:"的URL(例如"classpath:../services.xml")这样引用,如果这样做的话运行时解析程序(resolution process)会选择“最近的”类路径——根目录,然后找到它的上层目录,类路径可能会被配置到错误的目录上。

您随时可以使用完全限定的资源地址而不是相对路径,例如:"file:C:/config/services.xml"或"classpath:/config/services.xml"。但是,请注意,您将应用程序耦合到了特定的绝对位置。最好对这种绝对路径使用间接的引用,例如通过"${…}"占位符解析运行时的JVM系统属性。

import指令是bean命名空间自身提供的一个功能。普通的bean定义以外的其他配置功能可以在选择Spring提供的XML命名空间中获得,例如,“context”和“util”命名空间。

Groovy Bean定义DSL

作为外部化配置元数据的另一个例子,bean的定义也可以在Spring的Groovy Bean定义DSL中表示,像Grails框架中那样。通常这样的配置将存在于“.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配置名称空间。还允许通过“importBeans”指令导入XML bean定义文件。


书籍推荐