2011-03-02 28 views
31

我目前正在基於Spring 3.1.0.M1的基於註釋的Web應用程序上工作,並且我在解決應用程序的一個特定位置中的屬性佔位符時遇到問題。如何以編程方式解決Spring中的屬性佔位符

這是故事。

1)在我的web應用程序的上下文(由DispatcherServlet的加載),我有

MVC-config.xml中:

<!-- Handles HTTP GET requests for /resources/version/** --> 
<resources mapping="/${app.resources.path}/**" location="/static/" cache-period="31556926"/> 

... 

<!-- Web properties --> 
<context:property-placeholder location=" 
    classpath:app.properties 
    "/> 

2)內部app.properties,有2個屬性,除其他:

app.properties:

# Properties provided (filtered) by Maven itself 
app.version: 0.1-SNAPSHOT 
... 

# Static resources mapping 
app.resources.path: resources/${app.version} 

3)我有我的JS JSP定製標記P 2.1模板。這個標籤負責根據環境設置,應用版本,彈簧主題選擇等完成資源路徑構建。自定義標籤類擴展了spring:url實現類,所以它可以被認爲是一個普通的url標籤,但是有一些關於正確路徑的額外知識。

我的問題是我無法在我的JSP自定義標記實現中正確解析$ {app.resources.path}。 JSP自定義標籤由servlet容器管理,而不是Spring,因此不參與DI。所以我不能僅僅使用通常的@Value(「$ {app.resources.path}」)並且讓Spring自動解決它。

我在那裏有所有的Web應用程序上下文實例,所以我必須通過編程解決我的財產。

到目前爲止,我嘗試:

ResourceTag.java:

// returns null 
PropertyResolver resolver = getRequestContext().getWebApplicationContext().getBean(PropertyResolver.class); 
resolver.getProperty("app.resources.path"); 


// returns null, its the same web context instance (as expected) 
PropertyResolver resolver2 = WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext()).getBean(PropertyResolver.class); 
resolver2.getProperty("app.resources.path"); 


// throws NPE, resolver3 is null as StringValueResolver is not bound 
StringValueResolver resolver3 = getRequestContext().getWebApplicationContext().getBean(StringValueResolver.class); 
resolver3.resolveStringValue("app.resources.path"); 


// null, since context: property-placeholder does not register itself as PropertySource 
Environment env = getRequestContext().getWebApplicationContext().getEnvironment(); 
env.getProperty("app.resources.path"); 

所以現在我有點堅持這一點。我知道解決佔位符問題的能力在上下文中的某個位置,我只是不知道正確的方法。
任何幫助或想法檢查是高度讚賞。

回答

13

我想,而不是專注於上下文佔位的內部工作,你可以簡單地定義一個新的UTIL:性能是這樣的:

<util:properties id="appProperties" location="classpath:app.properties" /> 

,並在你的代碼,這樣使用它:

Properties props = appContext.getBean("appProperties", Properties.class); 

或者這樣的地方,你可以做DI:

@Value("#{appProperties['app.resources.path']}") 
+0

謝謝Ritesh。我想我可以使用這個解決方案,以防萬一找不到更優雅的東西。 – 2011-03-03 02:39:58

+0

已將此答案標記爲已接受,但找到純程序化解決方案總是很有趣。 – 2011-03-09 18:13:59

+0

@Max Alexejev您還可以擴展PropertyPlaceholderConfigurer並將在第二個參數中傳遞的已解析屬性捕獲到processProperties方法。但是,您將不得不使用bean配置而不是上下文:property-placeholder。 – Ritesh 2011-03-09 18:50:43

1

還有一個可能的解決方案:讓標籤CLAS可通過AspectJ進行配置,並啓用編譯時或加載時編織。然後,我可以在我的自定義標記中使用常規的Spring @Value註釋。 但是,實際上,我不想僅僅因爲幾個類而建立編織基礎架構。仍然在尋找一種通過ApplicationContext解析佔位符的方法。

23

自3.0版以來,Spring在beanFactory中保留了一個字符串解析器列表。 您可以使用它像這樣:如標註屬性所以也許我們繞開它的使用

String value = appContext.getBeanFactory().resolveEmbeddedValue("${prop}"); 

的Javadoc狀態此方法作爲解決內含價值,但它的作品。

+0

非常感謝你!正在尋找一段時間來尋求一種乾淨的方式來查詢環境。 – 2013-05-13 12:27:57

30

自Spring 3.0.3以來有EmbeddedValueResolverAware,它將以與使用appContext.getBeanFactory().resolveEmbeddedValue("${prop}")調用的另一個帖子所述方式相同的方式工作。

爲了解決這個問題:

  1. 讓你的類實現EmbeddedValueResolverAware接口,您將得到解析注射您

  2. 然後,你就可以檢索屬性爲代碼證明片段:

    String propertyValue = resolver.resolveStringValue("${your.property.name}"); 
    

然後你BE一個不需要依賴ApplicationContext來檢索你需要的屬性。

+3

這是解決問題的一種非常簡單的方法。對於任何未來的讀者,只需將接口EmbeddedValueResolverAware添加到您希望能夠以編程方式解析屬性的Spring類管理類中,實現setter方法並使用寫入的代碼來解析。 – Alex 2014-08-22 01:19:32

+0

事實上,亞歷克斯值得讚揚他的評論。你不想編輯答案嗎? – Heri 2014-12-11 20:58:28

+0

這是我見過的唯一可以接受的方法,用於編寫必須適用於多個Spring應用程序的共享組件/配置。您不希望所述代碼依賴於特定應用程序如何從文件或其他方式獲取其屬性配置。 – 2017-10-11 12:24:09

4

一個選項是將一個PropertySource(這裏是MapPropertySource來舉例說明內存中的配置)添加到ConfigurableEnvironment並要求它爲您解析屬性。

public class Foo { 

    @Autowired 
    private ConfigurableEnvironment env; 

    @PostConstruct 
    public void setup() { 
     env.getPropertySources() 
      .addFirst(new MapPropertySource("my-propertysource", 
       ImmutableMap.<String, Object>of("your.property.name", "the value"))); 
     env.resolvePlaceholders("your.property.name"); 
    } 
} 

可選註釋Foo@Configuration享受編程配置的功率贊成XML

相關問題