1

I have a xmlConfiguration bean to loading a SystemProperty.xml file as below

<bean
    id="xmlConfiguration"
    class="org.apache.commons.configuration.XMLConfiguration"
    lazy-init="true">
    <constructor-arg type="java.lang.String">
        <value>SystemProperty.xml</value>
    </constructor-arg>
    <property name="expressionEngine">
        <bean class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine" />
    </property>
</bean>

It works fine, however, I have to set delimiterParsingDisabled to true in XMLConfiguration, so I change bean for adding a propery delimiterParsingDisabled

<bean
    id="xmlConfiguration"
    class="org.apache.commons.configuration.XMLConfiguration"
    lazy-init="true">
    <constructor-arg type="java.lang.String">
        <value>SystemProperty.xml</value>
    </constructor-arg>
    <property name="expressionEngine">
        <bean class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine" />
    </property>
    <property name="delimiterParsingDisabled">
        <value type="java.lang.Boolean">true</value>
    </property>
</bean>

But, this wouldn't work well. Due to the setDelimiterParsingDisabled() must be called before loading in the file. Therefore, I have to call load(String fileName) of XMLConfiguration after called setDelimiterParsingDisabled()

I have used MethodInvokingFactoryBean for this way, but got any exception as below

org.apache.commons.configuration.ConfigurationException: No file name has been set!
at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:409)
at org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.save(AbstractHierarchicalFileConfiguration.java:214)
at devicemanage.system.SystemConfigurationServiceImpl.saveSystemProperty(SystemConfigurationServiceImpl.java:232)
at datacollection.service.DataCollectionServiceImpl.syncWithDataCollection(DataCollectionServiceImpl.java:786)
at devicemanage.utility.SyncWithDCListener$1.run(SyncWithDCListener.java:51)

It seems that the file doesn't be set into XMLConfiguration, my MethodInvokingFactoryBean has described as below

<bean id="xmlConfigurationMethodInvokingBean"  
     class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
     <property name="targetObject" ref="xmlConfiguration" />  
     <property name="targetMethod" value="load" />
     <property name="arguments" value="SystemProperty.xml" />  
 </bean>

And of cause, change my xmlConfiguration bean to not loading file while new the constructor as below

<bean
    id="xmlConfiguration"
    class="org.apache.commons.configuration.XMLConfiguration"
    lazy-init="true">
    <property name="expressionEngine">
        <bean class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine" />
    </property>
    <property name="delimiterParsingDisabled">
        <value type="java.lang.Boolean">true</value>
    </property>
</bean>

Not sure is that I have the wrong way to using MethodInvokingFactoryBean or I have an error used of the arguments to passing a fileName String into load()

Any help is appreciated.

Bruce
  • 647
  • 2
  • 12
  • 30

1 Answers1

1

First way

I would suggest you to create your own inherited class and declare init-method:

package beans;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;

public class CustomXMLConfiguration extends XMLConfiguration {

    private String loadFileName;

    private void init() throws ConfigurationException {
        this.load(fileName);
    }

    public String getLoadFileName() {
        return loadFileName;
    }

    public void setLoadFileName(String fileName) {
        this.loadFileName = fileName;
    }
}

And into the configuration you can use this class in the following way:

<bean id="xmlConfiguration" class="beans.CustomXMLConfiguration" lazy-init="true"
                            init-method="init">
    <property name="expressionEngine">
        <bean class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine" />
    </property>
    <property name="delimiterParsingDisabled">
        <value type="java.lang.Boolean">true</value>
    </property>
    <property name="loadFileName" value="SystemProperty.xml"/>
</bean>

init() method will be invoked right after bean will be initialized.

Second way

You can use bean of MethodInvokingBean class. Bean of this class just invoking of target method:

<bean class="org.springframework.beans.factory.config.MethodInvokingBean">
    <property name="targetObject" ref="xmlConfiguration"/>
    <property name="targetMethod" value="load"/>
    <property name="arguments" value="SystemProperty.xml"/>
</bean>

Personally I would prefer first variant, because of more flexible customization and there is not redundant instance of bean. But you can choose anyone.

Hope this will be helpful.

Ken Bekov
  • 13,696
  • 3
  • 36
  • 44