【问题标题】:How to use datasource conditionally in applicationContext.xml如何在 applicationContext.xml 中有条件地使用数据源
【发布时间】:2015-02-08 19:55:03
【问题描述】:

我正在使用 Spring 创建一个 GAE 项目,该项目也将使用云 SQL。在本地测试此应用程序时,我指向我的本地 MySQL 环境,但是当我将其部署到 GAE 时,它将指向云 SQL 实例。所以我想根据环境在数据源 bean 中配置我的 driverName。为此,我们通常在我们的 java 代码中使用以下代码

if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
    // Load the class that provides the new "jdbc:google:mysql://" prefix.
    Class.forName("com.mysql.jdbc.GoogleDriver");
    url = "jdbc:google:mysql://<your-project-id>:<your-instance-name>/<your-database-name>?user=root";
} else {
    // Local MySQL instance to use during development.
    Class.forName("com.mysql.jdbc.Driver");
    url = "jdbc:mysql://127.0.0.1:3306/<your-database-name>?user=root";
}

现在我想使用 Spring Expression 语言在 applicationcontext.xml 中实现相同的目的。我以前没有这样做过,也无法实现。请指导我。这是我尝试过的

<bean id="isDev" class="java.lang.Boolean">
    <constructor-arg value="#{ systemProperties[environment.value] == SystemProperty.Environment.Value.Development ? true : false }" />
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="#{ isDev ? com.mysql.jdbc.Driver : com.mysql.jdbc.GoogleDriver }" />
.
.
.

但是我遇到了异常,附加了一部分异常

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sandeepapplabs.custengage.services.FeedbackFormService com.sandeepapplabs.custengage.controllers.FeedbackFormController.feedbackFormService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sandeepapplabs.custengage.daos.FeedbackFormDAO com.sandeepapplabs.custengage.services.impl.FeedbackFormServiceImpl.feedbackFormDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormDAO' defined in ServletContext resource [/WEB-INF/custengage-servlet.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/custengage-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is java.lang.NullPointerException

【问题讨论】:

    标签: mysql spring google-app-engine spring-el


    【解决方案1】:

    我相信您需要引用类名以使其成为文字...

    ... 'com.mysql.jdbc.Driver' ...

    但是使用 Spring Profiles](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-definition-profiles-xml) 并启用所需的配置文件会更容易。

    【讨论】:

      【解决方案2】:

      您可以使用 Spring 配置文件来更改具体的 bean 类。假设您有 2 个配置文件:“prod”和“dev”。你的 bean 方法应该有 @Profile 注释,如下所示:

      @Configuration
      public class AppConfig {
      
      ...
      
        @Bean
        @Profile("prod")
        public Object prodDataSource() { 
      
          return new ...
        }
      
        @Bean
        @Profile("dev")
        public Object getDataSource() throws Exception {
          return new ...
        }
      
       }
      

      如果你使用的是Maven,可以通过pom.xml选择profile:

      <profiles>
          <profile>
              <id>dev</id>
              <activation>
                  <activeByDefault>true</activeByDefault>
              </activation>
              <properties>
                  <spring.profile>dev</spring.profile>
              </properties>
          </profile>
      
          <profile>
              <id>prod</id>
              <activation>
                  <activeByDefault>false</activeByDefault>
                  <property>
                      <name>prod</name>
                  </property>
              </activation>
              <properties>
                  <spring.profile>prod</spring.profile>
              </properties>
          </profile>
      
      </profiles>
      

      您可以通过-D 传递配置文件选择参数,例如:mvn -Dprod clean compile test install

      编辑:

      在application.properties 以下属性选择配置文件:

      spring.profiles.active=${spring.profile}
      

      【讨论】:

      • 我没有在我的项目中使用 Maven @Efe :( 我会按照你提到的方式尝试使用 Spring 配置文件
      • 如果您不使用 Maven,您可以简单地更改位于 Spring 属性文件中的 spring.profiles.active 属性(通常是 application.properties)
      猜你喜欢
      • 2013-01-20
      • 2014-12-20
      • 2016-05-19
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 2021-06-04
      • 2015-05-25
      相关资源
      最近更新 更多