I have a web project where BeanUtils
is used to manipulation beans.
In my code, in order to make BeanUtils
transfer string records into java.util.Date
fields properly, a DateConverter
is registered into ConvertUtils
class like that:
ConvertUtils.register(dateConverter, Date.class);
Moreover, In my project, different date formats is needed in different Actions, So, I registered different converters in different actions like that:
public void Action1(){
DateTimeConverter dtConverter = new DateConverter();
dtConverter.setPatterns(dateFormats1);
ConvertUtils.register(dtConverter, Date.class);
...
BeanUtils.populate(myBean1, hashMap1);
}
public void Action2(){
DateTimeConverter dtConverter = new DateConverter();
dtConverter.setPatterns(dateFormats2);
ConvertUtils.register(dtConverter, Date.class);
...
BeanUtils.populate(myBean2, hashMap2);
}
But later, I noticed that registered Converter with same target class (Date
here) will replace each other. So if ConvertUtils.register
operation is not thread local, problems caused by concurrence may happen here, even through my website haven`t met any yet.
So, would converter registered in one thread replace converter registered in another thread? If so, is there any work around for my circumstance?
Apache commons beanutils uses a ContextClassLoaderLocal to manage the framework's instances. The concept is similar to a ThreadLocal
except that it binds an instance to a thread's context class loader.
So when the threads that execute Action1
and Action2
share the same context class loader a change to the ConverterUtils
in one action will affect the other.
To be safe you can use an own instance of a BeanUtilsBean
in each action, e.g.
public void Action1(){
BeanUtilsBean beanUtils = new BeanUtilsBean();
ConvertUtilsBean convertUtils = beanUtils.getConvertUtils();
DateTimeConverter dtConverter = new DateConverter();
dtConverter.setPatterns(dateFormats1);
convertUtils.register(dtConverter, Date.class);
...
beanUtils.populate(myBean1, hashMap1);
}
Of course it would be better to configure the BeanUtilsBean
once in the constructor of your class and just use it.