开发者

Spring Bean (Mis-)Configuration

开发者 https://www.devze.com 2023-04-13 08:31 出处:网络
I\'m new to Spring and am trying to accomplish two objectives: I want to keep my application\'s config data (server IPs, credentials, etc.) in a deployment-specific properties file (`environment.pro

I'm new to Spring and am trying to accomplish two objectives:

  1. I want to keep my application's config data (server IPs, credentials, etc.) in a deployment-specific properties file (`environment.properties`)
  2. I want to use Spring for dependency injection of this config data into my application

So first we have my environment.properties file:

ftpServer=http://example.com/ftp
ftpUser=exampleUser
ftpPassword=examplePassword

Next my Spring config file, which contains a propertyConfigurer bean that I believe I have set up correctly:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="placeholderPrefix" value="${" />
    <property name="placeholderSuffix" value="}" />
    <property name="locations">         
        <value>classpath:environment.properties</value>     
    </property> 
</bean>

<bean id="ftpServer" class="jav开发者_开发技巧a.lang.String">
    <constructor-arg type="java.lang.String" value="${ftpServer}"/>
</bean>

<bean id="ftpUser" class="java.lang.String">
    <constructor-arg type="java.lang.String" value="${ftpUser}"/>
    <constructor-arg></constructor-arg>
</bean>

<bean id="ftpPassword" class="java.lang.String">
    <constructor-arg type="java.lang.String" value="${ftpPassword}"/>
</bean>

And finally the source code where I want this deployment-specific data injected into:

public void connectToServerAndDoSomething()
{
    String strServer = oAppContext.getBean("ftpServer");
    String strUser = oAppContext.getBean("ftpUser");
    String strPassword = oAppContext.getBean("ftpPassword");

    FTPClient oFTP = new FTPClient(strServer, strUser, strPassword);
}

My question:

I'm getting a Spring bean validation error in my config file:

SEVERE: Exception sending context initialized event to listener instance of class     
org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException:   
Configuration problem: Unexpected failure during bean definition parsing
Offending resource: ServletContext resource [/WEB-INF/app-config.xml] Bean 'ftpUser'; nested exception is 
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: 
Configuration problem: <constructor-arg> element must specify a ref or value
Offending resource: ServletContext resource [/WEB-INF/app-config.xml] Bean 'ftpUser' -> Constructor-arg

Since I'm new to Spring, I don't know where to start. Is it not possible to use Spring to inject Java types like Strings, or is it not possible to use Spring the way I am? Anyway to circumvent this?

Thanks in advance!


The actual error you get is due to having an empty constructor-arg element for the ftpUser bean. Remove the duplicate

<constructor-arg></constructor-arg>

I also think you are going about this a bit incorrectly. The typical way would be to define a bean for the FTPClient like this:

<bean id="ftpClient" class="your.package.FTPClient">
   <constructor-arg value="${ftpServer}" />
   <constructor-arg value="${ftpUser}" />
   <constructor-arg value="${ftpPassword}" />
</bean>


The problem is that actualy means nothing. Spring has 3 ways of specifying

  1. Using ref attribute to reference another bean
  2. Using value - passing simple value. Note that spring comes with a pack of Convertors, which can convert string to numbers/booleans etc...
  3. Using nested bean tag or just passing the value. In your case you don't pass value at all. You can change it to be:

<constructor-arg value=""/>

and it will be fine


There's multiple issues here:

  • <constructor-arg> element must specify a ref or value this is due to the fact that in your bean definition you have an emptu constructor-arg tag. The xml file is simply invaliated by the schma as that tag must have a "value" or "ref" attribute:

Remove the 2nd constructor-arg tag.

  • in order to have parametrisation in a .properties file, you simply create that file and add properties/values to it, then in your spring context you make a refference to that file like, and then you use ${propertyName} placeholder to get the value of a certain property in your xml beans file:

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
          <value>classpath:my.properties</value>
      </list>
    </property>
    

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号