7

在使用 Spring Batch Admin 时,它会尝试为 dataSource、transactionManager 等提供一些默认值。

如果您想覆盖这些默认值,您可以在META-INF/spring/batch/servlet/override/文件夹下创建自己的 xml bean 定义,并在引导期间保证默认属性将被覆盖。

在 spring-batch-admin 中,在 data-source-context.xml 中使用此定义定义了 dataSource 默认值

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${batch.jdbc.driver}" />
    <property name="url" value="${batch.jdbc.url}" />
    <property name="username" value="${batch.jdbc.user}" />
    <property name="password" value="${batch.jdbc.password}" />
    <property name="testWhileIdle" value="${batch.jdbc.testWhileIdle}"/>
    <property name="validationQuery" value="${batch.jdbc.validationQuery}"/>
</bean>

现在,我想用 JNDI 数据源覆盖这个数据源,所以我删除了类似的属性行batch.jdbc.driverbatch.jdbc.url并具有以下 jndi 定义

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName" value="java:comp/env/jdbc/dbconn" />
</bean> 

正如您可能很容易猜到的那样,系统首先尝试初始化 data-source-context.xml 中定义的 dataSource bean,并且由于它找不到属性值 batch.jdbc.* 的任何值,因此它失败并出现异常。

无法解析字符串值 [${batch.jdbc.driver}] 中的占位符“batch.jdbc.driver”

由于我将使用 JNDI 并且不想处理这些属性值,因此我无法继续。

在这种情况下如何覆盖 dataSource 的任何想法?

4

2 回答 2

6

在 Spring Batch Admin 中,正在加载 2 个 Spring ApplicationContext:

  • servlet-config.xml
  • webapp-config.xml

servlet-config.xml 有这些导入:

<import resource="classpath*:/META-INF/spring/batch/servlet/resources/*.xml" />
<import resource="classpath*:/META-INF/spring/batch/servlet/manager/*.xml" />
<import resource="classpath*:/META-INF/spring/batch/servlet/override/*.xml" />

webapp-config.xml 有这些导入:

<import resource="classpath*:/META-INF/spring/batch/bootstrap/**/*.xml" />
<import resource="classpath*:/META-INF/spring/batch/override/**/*.xml" />

servlet-config.xml 配置 servlet,webapp-config.xml 配置(后端部分)应用程序。问题是 dataSource bean 是第二个配置的一部分/定义,而不是第一个。因此,当您将 dataSource bean 添加到 servlet 配置(/META-INF/spring/batch/servlet/override/*.xml)的覆盖时,正如您所做的那样,您将新 bean 添加到第一个上下文,而不是覆盖第二个上下文的 dataSource bean。

因此,您需要将自定义 data-source-context.xml 放在 META-INF/spring/batch/override/ 下,而不是 META-INF/spring/batch/servlet/override/

然后它工作,你甚至不会得到Could not resolve placeholder 'batch.jdbc.driver' in string value [${batch.jdbc.driver}]错误。

于 2013-09-20T13:00:00.417 回答
3

从 Spring 3.1 开始,“配置文件”功能允许您根据您所在的环境设置数据源“源”。(用于本地测试的嵌入式,用于部署的 JNDI。)

这看起来像下面这样;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- "production" datasource -->
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/dbconn"/>

    <!-- profile for "local" testing -->
    <beans profile="local">
            <!-- datasource that only gets created in that active profile -->
        <jdbc:embedded-database id="dataSource" type="H2"/>
    </beans>


</beans>

在此示例中,当“活动配置文件”设置为“本地”时,它会覆盖 jndi-lookup 数据源。

于 2013-04-18T10:52:47.497 回答