2013-02-25 103 views
2

我有一個自定義ApplicationContext類,我嘗試以編程方式加載PropertyPlaceholderConfigurer,然後在我的XML配置文件中使用佔位符。PropertyPlaceholderConfigurer無法以編程方式加載

我已經試過三種不同的方法,到目前爲止,每一次我得到這樣一個錯誤:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '${domain}.testId' is defined 

我做錯了嗎?

Context類

public class MyApplicationContext extends GenericApplicationContext { 
    public MyApplicationContext (String... locations) throws IOException { 

     // method one 
     ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this); 
     scanner.scan("com.my.package"); 

     // method two 
     new MyPropertyPlaceholderConfigurer().postProcessBeanFactory(getBeanFactory()); 

     // method three 
     getBeanFactory().registerSingleton("propertyPlaceholderConfigurer", new MyPropertyPlaceholderConfigurer()); 

     // load XML config files 
     XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(this); 
     for (String location : locations) { 
      xmlReader.loadBeanDefinitions(location); 
     } 
    } 
} 

XML

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

    <bean id="test.testId" class="java.lang.String"> 
     <constructor-arg value="this is the test value" /> 
    </bean> 

    <bean id="prod.testId" class="java.lang.String"> 
     <constructor-arg value="this is the prod value" /> 
    </bean> 

    <alias name="${domain}.testId" alias="testId" /> 

</beans> 

使用

MyApplicationContext context = new MyApplicationContext(
    new String[] { "test.xml" }); 
Assert.assertEquals("this is the test value", context.getBean("testId")); 
+0

爲什麼你需要一個自定義上下文來包含一個'PropertyPlaceholderConfigurer'甚至你自己定製的上下文? – beny23 2013-02-25 20:21:10

+0

我的上下文類也做包掃描和日誌初始化。我只是沒有在我的示例代碼中包含額外的東西。我對Spring很新,但它似乎是包含所有這些東西的合理位置。我錯了嗎? – MikeWyatt 2013-02-25 20:42:32

回答

0

這是標準的路怎麼麥e您的屬性可在配置文件中訪問。

<util:list id="locations"> 
    <value>classpath:appconfig.properties</value> 
    <value>classpath:jdbc.properties</value> 
</util:list> 

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" 
     p:ignoreResourceNotFound="true" 
     p:locations-ref="locations" /> 

<!-- bean that uses properties --> 
<bean id="dataSource" 
     class="com.mchange.v2.c3p0.ComboPooledDataSource" 
     p:driverClass="${jdbc.driver}" 
     p:jdbcUrl="${jdbc.url}" 
     p:user="${jdbc.user}" 
     p:password="${jdbc.pw}" 
     p:initialPoolSize="5" 
     p:minPoolSize="5" 
     p:maxPoolSize="50" 
     p:idleConnectionTestPeriod="5" /> 

另一個非常有用的方法如何「注入」在任何地方你的配置文件屬性中使用maven:您使用相同的語法${property-name}但值在Maven構建過程中所提供的 - 這是Maven配置的相關部分:

<properties> 
<jdbc.url>jdbc:mysql://localhost:3306/dummyuserdb</jdbc.url> 
<jdbc.user>root</jdbc.user> 
<jdbc.pw>admin</jdbc.pw> 
</properties> 

,你必須包括在Maven的過濾資源的Spring的配置目錄:

<build> 
    <resources> 
    <resource> 
     <directory>${basedir}/src/main/webapp/WEB-INF/spring-config</directory> 
     <filtering>true</filtering> 
     </resource> 
</resources> 

或者如果你喜歡Java的配置:

@Configuration 
@PropertySource(value = "config/jdbc.properties") 
public class BaseWebConfig { 

    @Autowired Environment env; 

    @Bean 
    public MyBean myBean() { 
     MyBean myBean = new MyBean(); 
     String propertyValue = env.getProperty("my-property-name"); 
     // do something with myBean and propertyValue 
     return myBean; 
    } 
} 

}

0

如果你只是想用自己的自定義MyPropertyPlaceholderConfigurer(假設它擴展PropertyPlaceholderConfigurer,那麼所有你需要做的就是把它作爲bean在您的應用程序的上下文中,它會爲你做所有的休息:

<bean class="my.pkg.MyPropertyPlaceholderConfigurer" /> 
+0

這是否需要配置文件,然後?它不能在代碼中完成? – MikeWyatt 2013-02-25 20:45:11

+0

你已經有了一個配置XML('test.xml'),這就是它要去的地方。 – beny23 2013-02-25 20:58:34

+0

爲什麼使用配置XML比將組件掃描爲更好或不同?我的系統比我的問題中顯示的三個文件稍微複雜一點,我希望有更好的解決方案,而不是將其添加到我的主XML或創建第二個。 – MikeWyatt 2013-02-25 21:09:25

2

我很欣賞答案關於如何定義bean,但事實證明問題簡單得多。我正在加載這個bean,但是在加載所有的bean之後我沒有正確地初始化我的上下文。一個簡單的調用refresh()就可以實現。

MyApplicationContext context = new MyApplicationContext(
    new String[] { "test.xml" }); 

context.refresh(); // this runs BeanFactoryPostProcessors like 
        // MyPropertyPlaceholderConfigurer, among other things 

Assert.assertEquals("this is the test value", context.getBean("testId")); 
+0

你並不孤單,謝謝你發佈你的解決方案! – Brian 2013-03-25 17:36:14

相關問題