13

Tôi có tệp Spring application-context.xml với PropertyPlaceholderConfigurer để lấy các giá trị của thuộc tính từ tệp .properties. Thư mục nguồn chính và thử nghiệm có tệp .properties riêng biệt. Vấn đề là tôi cần sử dụng các biến môi trường trong tệp .properties. Nhưng khi tôi làm điều đó theo cách sau:PropertyPlaceholderCấu hình và biến môi trường trong các tệp .properties

property.name=${env.SYSTEM_PROPERTY} 

Tôi nhận được lỗi sau:

org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'beanName' defined in class path resource [com/example/applicationContext.xml]: Could not resolve placeholder 'env.SYSTEM_PROPERTY' 

trong khi giữ chỗ configurer định nghĩa là

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath:com/example/application.properties"/> 
</bean> 

Bất kỳ ý tưởng làm thế nào để làm cho property.name được hiểu là biến môi trường (và không phải là trình giữ chỗ)?

Trân trọng, Dmitriy.

Trả lời

23

Tôi có thể thay đổi hoàn toàn giải pháp: tiêm trực tiếp thuộc tính hệ thống, trái ngược với việc tiêm thuộc tính tham chiếu đến thuộc tính hệ thống

Ví dụ:

@Value("#{ systemProperties['JAVA_MY_ENV'] }") 
private String myVar; 

hoặc

<property name ="myVar" value="#{systemProperties['JAVA_MY_ENV']}"/> 

tôi sử dụng một configurer placeholder tài sản như thế này

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
    <list> 
     <value>classpath:someprops.properties</value> 
    </list> 
    </property> 
    <property name="ignoreResourceNotFound" value="true" /> 
    <property name="searchSystemEnvironment" value="true" /> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> 

Bạn cũng phải nhớ để vượt qua các tham số vào chương trình sử dụng

-DJAVA_MY_ENV=xyz 

này khi bạn chạy phiên bản sản xuất bạn có thể vượt qua một điều và khi bạn đang chạy thử nghiệm khác.

Ngoài ra những gì tôi thường những gì tôi làm là một cái gì đó như thế này:

<property name="locations"> 
    <list> 
     <value>classpath:someprops.properties</value> 
     <value>classpath:someprops-{environment}.properties</value> 
    </list> 
    </property> 

nơi môi trường là sản/giai đoạn/kiểm tra/int/ci/local (1 cho mỗi môi trường - bạn có thể chỉ có 2 hoặc 3 cho hiện nay). Bạn có thể chuyển biến môi trường cho chương trình. Bất kỳ thuộc tính nào sẽ giống nhau bất kể sản xuất/chạy trên máy tính/thử nghiệm cục bộ của bạn có nằm trong tệp thuộc tính someprops.properties hay không. Bất kỳ cái nào cụ thể đối với môi trường/cách nó đang chạy như sẽ đi vào tệp cụ thể hơn (bạn nên đặt nó trong tệp someprops.properties cũng như mặc định trừ khi cơ chế ghi đè)

Ví dụ: trong classpath: someprops.properties

url=www.mysite.com 

trong classpath: someprops-local.properties

url=localhost 

Bằng việc sử dụng ý tưởng cơ bản này bạn có thể tách kiểm tra và tính chất hoạt động bình thường của chương trình một cách sạch sẽ.

+0

này là khá tốt. Tuy nhiên một vấn đề là quên để xác định một biến thời gian chạy sản xuất lỗi thời gian chạy phức tạp, như config_xxx tập tin không tìm thấy và thích. Để cải thiện tình hình đó, tôi đăng ký một bean thực hiện các giao diện mùa xuân đặc biệt như thế này: class EnvironmentReporter thực hiện PriorityOrdered, BeanFactoryPostProcessor, EnvironmentAware {...} environment.getProperty cho phép tôi kiểm tra các thuộc tính mong đợi và thất bại trước khi bất kỳ bean nào khác nhận được tạo. – Federico

7

Sử dụng:

<context:property-placeholder location="classpath:env.properties"/> 

Thay đổi của bạn:

property.name=${env.SYSTEM_PROPERTY} 

Để:

property.name=${SYSTEM_PROPERTY} 

Tôi đang sử dụng Spring 3.0.4.RELEASE, nhưng tôi không có ý tưởng khi điều này đã được giới thiệu.

+1

Cảm ơn bạn rất nhiều. Tôi đã giải quyết vấn đề bằng cách sử dụng lớp trợ giúp tìm kiếm tài sản VM, sau đó biến môi trường và sau đó sử dụng giá trị mặc định. Ngay bây giờ nó là cách linh hoạt hơn cho tôi. Nhưng vẫn cảm ơn, tôi sẽ cố gắng theo cách của bạn thời gian tới tôi sẽ làm điều này. –

+1

lạ - sử dụng mùa xuân 3.0.4, điều này dường như không hoạt động –

0

tôi đã sử dụng cách tiếp cận benkiefer, nhưng tôi đã có thêm một người biết lắng nghe để web.xml:

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
Các vấn đề liên quan