是否可以从Hibernate中的项目结构外部访问database.properties文件?

时间:2016-02-03 09:34:11

标签: java xml spring hibernate servlets

我正在尝试使用项目外的database.properties文件设置hibernate项目的配置。试图在web.xml中设置如下

<context-param>
        <param-name>propertiesLocation</param-name>
        <param-value>classpath:resources/database.properties</param-value>
    </context-param> 

和sdnext-servlet.xml

<context:property-placeholder location="file:${#{contextParameters.propertiesLocation}" /> <br><br>

但未能达到所需的输出。 仍然高于配置强制将属性文件放在项目结构中可以做什么,以便可以在项目之外访问?

以下配置适用于项目内的database.properties文件。 <context:property-placeholder location="classpath:resources/database.properties"/>

需要做哪些更改才能使项目可以访问项目之外的database.properties文件。

web.xml文件是

<servlet>
        <servlet-name>sdnext</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/sdnext-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>sdnext</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

sdnext-servlet.xml是

<context:property-placeholder location="classpath:resources/database.properties"/>
    <context:component-scan base-package="com.dineshonjava" />
    <tx:annotation-driven transaction-manager="hibernateTransactionManager" />

    <bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.dineshonjava.model.Employee</value>
                <value>com.dineshonjava.model.Books</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

3 个答案:

答案 0 :(得分:1)

如上所述,除了Spring之外,它与Hibernate或其他框架无关。这与你对占位符(处理)和Spring EL的误解有关。

您正尝试使用占位符配置<context:property-placeholder />。现在关于这一点,您在基础架构之前使用占位符来完全解析这些占位符实际上就位。

如果您真的想使用动态方式设置配置,则必须使用Spring EL。你实际上必须在xml 中进行编程。

您需要使用environment变量来解析已知位置的变量,例如系统环境,系统属性,jndi,servlet上下文等。使用getRequiredProperty(...)方法解析值。

<context:property-placeholder location="#{environment.getRequiredProperty('propertiesLocation')}" />

注意:这不起作用,因为location属性不了解EL。请改用普通PropertySourcesPlaceholderConfigurer

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="location" value="#{environment.getRequiredProperty('propertiesLocation')}" />
</bean>

现在您需要在某处定义名为propertiesLocation的属性,这可以是(取决于环境和环境的可能性)。

  • 系统环境变量
  • 系统属性(java -D)
  • Servlet上下文参数
  • Servlet Init参数
  • JNDI

在您的情况下,您想使用上下文参数

<context-param>
    <param-name>propertiesLocation</param-name>
    <param-value>classpath:resources/database.properties</param-value>
</context-param>

现在而不是classpath:resources/database.properties使用其他内容,例如file:/some/path/on/your/system/database.properties。有关支持的前缀的详细信息,请参阅resource loading上的参考指南。

但是你最好使用JNDI条目的系统环境变量,否则它仍然是静态的,你最好直接指定location="file:/some/path/on/your/system/database.properties

答案 1 :(得分:1)

按照@ user2004685建议,如果在location中提供属性文件的绝对路径,则可以通过定义包含文件的Maven属性来超越硬编码问题路径,在项目的构建周期中被替换。

答案 2 :(得分:0)

我在file:${#{contextParameters.propertiesLocation}中看到一个拼写错误,您没有使用}结束该属性。

试试这个:

<context:property-placeholder location="file:#{contextParameters.propertiesLocation}"/>