2012-01-19 54 views
19

Tôi đang làm việc trên một dự án với một số mô-đun riêng biệt, mỗi tệp có các tệp thuộc tính ngữ cảnh ứng dụng của riêng chúng. Tôi muốn có thể tải tất cả các thuộc tính này để chúng có thể được sử dụng cho độ phân giải trình giữ chỗ của Spring.Nhiều tệp thuộc tính trong Spring 3.0

Câu hỏi trước đã đề cập đến điều này và có một bài đăng blog tốt here mô tả cách sử dụng PropertyPlaceholderConfigurer trong mỗi ngữ cảnh, sắp xếp chúng theo mức độ ưu tiên và đặt ignoreUnresolveablePlaceholders thành true để các tệp thuộc tính này có thể tham chiếu chéo với nhau mà không thổi lên.

Tuy nhiên, điều này không giải quyết được sự cố của tôi vì tôi cũng muốn có thể sử dụng thuộc tính mà tôi đang tải cho một số độ phân giải trình giữ chỗ tùy chỉnh (từ một số tệp yaml tôi đang phân tích cú pháp). Điều này đòi hỏi phải sử dụng một PropertyPlaceholderHelper, đòi hỏi đối tượng Properties làm đối số.

Theo như tôi có thể biết, các giải pháp tiềm năng là:

1) Hợp nhất tất cả tệp thuộc tính vào một bean thuộc tính. Điều này sau đó có thể được sử dụng để tạo ra một PropertyPlaceholderConfigurer (cho độ phân giải giữ chỗ bên trong của Spring) và được sử dụng với một PropertyPlaceholderHelper (cho độ phân giải chỗ dành sẵn của riêng tôi)

2) Bằng cách nào đó cấu hình PropertyPlaceholderHelper để sử dụng tập hợp thuộc tính và sắp xếp thứ bậc của chúng, được tổ chức bởi PropertyPlaceholderConfigurers nếu tôi tiếp tục và làm theo lời khuyên của bài đăng trên blog đó.

Rất tiếc, tôi không thể tìm ra cách thực hiện một trong hai cách này. Mọi sự trợ giúp sẽ rất được trân trọng!

PS Dường như mùa xuân 3.1 sẽ là một trợ giúp lớn ở đây ... không may là chúng tôi chưa sẵn sàng chuyển sang đó nên tôi vẫn cần một giải pháp để giải quyết vấn đề này!

**** CHỈNH SỬA ****

Cảm ơn câu trả lời cho đến nay. Họ là những câu trả lời hay nhưng tiếc là sẽ không giúp tôi vì (và xin lỗi vì đã không đề cập đến điều này trước đó), chúng tôi hiện đang trong quá trình tách các mô-đun cốt lõi của dự án khỏi các mô-đun không phải lõi. Điều này có nghĩa là các mô đun cốt lõi và bối cảnh ứng dụng của chúng không thể mã hóa cứng tên của các tệp thuộc tính. Bực bội, quét classpath của Spring dường như bị hỏng, vì vậy các ký tự đại diện thuộc loại "classpath *: *. Properties" chỉ hoạt động khi xây dựng các mô-đun riêng lẻ, chứ không phải dự án cấp cao nhất (tôi tin đây là một vấn đề đã biết).

Câu hỏi là sau đó làm cách nào để hợp nhất các tệp thuộc tính được xác định trong các mô-đun không phải lõi thành các tệp thuộc tính hiện có được xác định trong các mô-đun chính. Tại thời điểm này tôi đang đi trước với một BeanPostProcessor - Tôi chỉ tự hỏi nếu có một cách đơn giản hơn/thanh lịch hơn để làm điều này?

Cảm ơn

+0

Tôi nghĩ bạn cần cung cấp ít nhất một phân đoạn dir không đổi, vì vậy 'classpath *: *. Properties' sẽ không hoạt động nhưng' classpath *: config/*. Properties' sẽ. – mrembisz

Trả lời

7

Sau Đoạn mã nên giúp bạn bắt đầu

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="corePlaceHolder"> 
    <property name="ignoreUnresolvablePlaceholders" value="true"/> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> 
    <property name="searchSystemEnvironment" value="true"/> 
    <property name="locations"> 
     <list> 
      <value>classpath*:config/*/config1/*.properties</value> 
      <value>classpath*:config/*/config2/*.properties</value> 
      <value>classpath*:config/*/config3/*.properties</value> 
      <value>classpath*:custom.properties</value> 
     </list> 
    </property> 
</bean>  

Bạn có thể lưu trữ các tập tin bất động sản ở sau phân cấp đảm bảo cấu hình có thể truy cập từ qua classpath

config 
    config1 
    a.properties 
    config2 
    b.properties 
    config3 
    c.properties 
custom.properties 
9

Bạn có thể thu thập nhiều tệp thuộc tính thành một bean khá dễ dàng:

<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="singleton" value="true"/> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="locations"> 
    <list> 
     <value>classpath*:default.properties</value> 
     <value>classpath*:overrides.properties</value> 
     <value>file:${APP_HOME}/**/*.properties</value> 
    </list> 
    </property> 
</bean> 

Ví dụ cụ thể này sẽ thu thập tất cả mặc định.properties, ghi đè.các thuộc tính trên các tệp classpath và thuộc tính trong APP_HOME của bạn. Bây giờ bạn có thể tham khảo bean này từ ProperyPlaceholderConfigurer hoặc trình xử lý tùy chỉnh của bạn.

6

Đây là tất cả các bạn cần làm:

<context:property-placeholder location="first.properties" order="0" ignore-unresolvable="true"/> 
<context:property-placeholder location="second.properties" order="0" ignore-unresolvable="true"/> 
<context:property-placeholder location="empty.properties" order="1"/> 

Vấn đề rất đơn giản: nếu một tài sản giữ chỗ không có giá trị cho một tài sản nhất định nó sẽ ném một ngoại lệ, mặc dù khác tài sản giữ chỗ có mặt .

Giải pháp sử dụng order để biết đây là property-placeholder và đặt ignore-unresolvable="true" trên tất cả những thứ khác, để mỗi property-placeholder đều có cơ hội cung cấp giá trị. Trong các dự án đa mô-đun, property-placeholder cuối cùng có thể trống hoặc cung cấp mặc định không an toàn.

Lưu ý: nếu bạn đặt tất cả phần giữ chỗ của thuộc tính thành ignore-unresolvable="true" Mùa xuân sẽ chỉ chuyển những gì bạn đã viết mà không ném ngoại lệ. Nếu tất nhiên bạn mong đợi nó là một cái gì đó khác hơn là String bạn chắc chắn sẽ nhận được một sự lừa dối như java.lang.NumberFormatException: For input string: "${something}" trong quá trình chuyển đổi định dạng.

Lưu ý: chỉ người đầu tiên (một có số thấp nhất order) property-placeholder với giá trị cho thuộc tính cụ thể sẽ được sử dụng. Nếu bạn muốn ghi đè thuộc tính sử dụng phạm vi order lớn hơn 01 hoặc property-override.

Được thử nghiệm với Mùa xuân 3.2.1, nhưng tất cả các thuộc tính được đề cập tồn tại trong 3.0. Xem JavaDoc of PropertyPlaceholderConfigurer

Các vấn đề liên quan