2013-02-25 69 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

相关问题