Issue
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.
Solution
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.
Answered By - Ken Bekov
Answer Checked By - Timothy Miller (JavaFixing Admin)