More readable Spring #Value parameter - java

I'm aware of that this topic might be considered as offtopic or convention/opinion based, but I have not found any other place that I could find solution for my problem.
I'm writing and Spring application, fully configured with annotations in Java. I'm loading the properties file with #PropertySource annotation:
#Configuration
#ComponentScan("myapp.app")
#PropertySource("app.properties")
public class ApplicationConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Let's assume, that I have app.properties file of following content:
property1=someProperty1Value
property2=someProperty2Value
I'm loading this value with following code:
#Service
public class MyServiceImpl implements MyService {
#Value("${property1}")
private String property1Value;
#Value("${property2}")
private String property2Value;
#Override
public void doStuff() {
System.out.println(property1Value);
System.out.println(property2Value);
}
}
This is working perfectly fine. On the other hand, I find it hard to maintain - if some will think that "property1" is not the best name for a property and would like to rename it, then it will be needed to find all strings "${property1}" and rename it. I tought that I could extract it to the constant class:
public final class Properties {
public static final String PROPERTY_1 = "${property1}";
public static final String PROPERTY_2 = "${property2}";
private Properties() {
}
}
This requires refactoring of the existing bindings to new constant values:
#Value(Properties.PROPERTY_1)
private String property1Value;
Looks nice, but I do not like the mess in the Properties class, I think it will be better to the constant values without bracelets:
public static final String PROPERTY_1 = "property1";
Which leads to another refactoring in the MyServiceImpl class:
#Value("${" + Properties.PROPERTY_1 + "}")
private String property1Value;
But boy, that's really ugly. I thought about extracting constant values to the Enum:
public enum Properties {
PROPERTY_1("property1"),
PROPERTY_2("property2");
private final String key;
private Properties(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public String getSpringKey() {
return "${" + getKey() + "}";
}
}
and use it like
#Value(Properties.PROPERTY_1.getSpringKey())
private String property1Value;
but then IDE reminded me, that annotation value has to be a constant.
After creating this enum, I thought that I might be over-thinking it, and it should be kept as simple as possible. Currently I came back to the solution with constants in format of
public static final String PROPERTY_1 = "${property1}";
Finally, I would like to ask you to provide another, nice-looking solution, or some reference links where I could read about some common solution.

Related

Where does Spring stores strings loaded from *.properties files?

I have this two files:
application.properties
// ... stuffs ...
spring.profiles.active=some_id
application-some_id.properties
// ... stuffs ...
some.string=value
I want to get the value of the property "some.string" from my java code like this:
Utility.java
public final class Utility {
public final static String SOME_STRING_VALUE = <Something>.getProperty("some.string");
private Utility() {
}
}
What should I write instead of <Something>? I know that working with spring I should use spring stuffs like #Value, #Component, etc ... and 99% of the project is like that. I'd like to have just this exception.
Try using the Environment API :
#Autowired
private Environment env;
.
.
env.getProperty("some.string");
Update :
To be able to use in a static context you can try using lazy instantiation like follow (but in this case you should remove final accessor) :
final class Utility {
#Autowired
private Environment env;
private static String SOME_STRING_VALUE;
public static String getStringValue() {
if (SOME_STRING_VALUE == null) {
SOME_STRING_VALUE = env.getProperty("some.string");
}
return SOME_STRING_VALUE;
}
private Utility() {}
}
Hope this helps

How can I interpolate a class constant in a Spring `#Value` annotation?

I want to let Spring assign a property value.
public class Foobar {
#Value("${example.property.foo:bar}")
private String foo;
}
Let's say I want to refer to example.property.foo in several different places, so I'd rather assign the flag as a constant on Foobar:
public class Foobar {
public static final String FOO_PROPERTY_FLAG = "example.property.foo";
}
The setting of example.property.foo=whatever happens elsewhere (as a system property, or in a #TestPropertySource).
How can I refer to FOO_PROPERTY_FLAG in the annotation? This works:
#Value("${" + FOO_PROPERTY_FLAG + ":bar}")
But it's kind of ugly. Can I use the "#{}" expression syntax here somehow?
#Value("${#{FOO_PROPERTY_FLAG}:bar}") // doesn't work; value is never injected
You can do something like:
public static final String KEY = "propertyName";
#Value("#{T(a.b.c.package.MyConstants).KEY}")
The important part is to specify package and class. Otherwise spring will try to lookup constant in BeanExpressionContext which is actually executing your SpEL
private #Value("${propertyName}") String propertyField;
No getters or setters!
With the properties being loaded via the config:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:propertyFile.properties" name="propertiesBean"/>
There's also the totally non-Xml version:
#PropertySource("classpath:propertyFile.properties")
public class AppConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Make sure and add in the namespace URI xmlns:p="springframework.org/schema/p"; to use the p: prefixed attributes

Managing configurations in java (initial config / save/load config)

I got a class Config wich looks like that:
public Class Config {
public static int someIntValue = 0;
public static String someText = "some text";
}
What i want to do now is saving and loading that config and there is also that inital config if there is no need to load another. So the config can change at any point in the programm.
What i came up with was a Singelton like pattern
public Class Config {
public static Config instance;
private int someIntValue = 0;
private int String someText = "some text";
public static Config getInstance(){
if(instance == null)
instance = new Config();
return instance;
}
public void setInstance(Config config){
this.instance = config;
}
//getter/setter
...
}
But in the end it doesnt look like the best approach and im not quite happy with it :/
Maybe you guys can help me out with a usual / "best practice" way to do that.
Best Regards
Made
I would just use java.util.Properties, or some wrapper around it. Another good approach is java bean and something like xstream to save/load stuff.
Usually in Java for configuration use properties files. And then use ResuorseBundle for reading properties.
Your "singleton" is not a Singleton in the conventional sense.
1) Field instance must be private
2) Remove SetInstance method
3) And you should make your singleton thread safe.
If you'd consider avoiding writing the boilerplate code around java.util.Properties, you can have a look at something that does it for you: OWNER API.
It's configurable to tailor your needs and it offers some additional neat features if compared to java.util.Properties (read the docs).
Example. You define an interface with your configuration parameters:
public interface ServerConfig extends Config {
int port();
String hostname();
#DefaultValue("42")
int maxThreads();
#DefaultValue("1.0")
String version();
}
Then you use it like this:
public class MyApp {
private static ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
private MainWindow window;
public MyApp() {
// you can pass the cfg object as dependency, example:
window = new MainWindow(cfg);
}
public void start() {
window.show();
}
public static void main(String[] args) {
// you can use it directly, example:
System.out.println("MyApp version " + cfg.version() + " copyright (c) ACME corp.");
MyApp app = new MyApp();
app.start();
}
}
You can define the cfg object as member instance on the classes where you need, or you can pass the instance to constructors and methods where you need it.
Version 1.0.4 will be released soon and it will include also "hot reload" and many improvements.

Design Pattern for one-time loaded configuration properties? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm often faced with the problem of storing, in memory, a few (possibly complex) configuration settings loaded from files on the filesystem. I'm wondering if there's a better way to architect a pattern to this problem, however, than what I've been using.
Essentially, my current solution involves three steps.
Build a singleton. Since data is persistent and guaranteed not to change through the runtime of the application, only one object instance should ever be needed.
When the first request for the object is made, create the object and read in from a file.
Expose data with getters.
This has the effect that a lot of my code looks like this:
MyConfiguration.getInstance().getWeightOfBomb(), which looks rather odd to me.
Is there a better way to handle this in a more semantic fashion?
Dependency Injection. You don't necessarily have to use a DI framework like Spring or Guice but you really want to avoid littering your code with singletons. You can still use a singleton in the implementation, but there is no reason the rest of your code needs to know that it is a singleton. Singletons are huge pain when unit testing and refactoring. Let your code reference an interface instead. e.g.,
interface MyConfig {
double getWeightOfBomb();
}
class SomeClass {
private MyConfig myConfig;
public void doSomething() {
myConfig.getWeightOfBomb();
}
}
class MyConfigImpl implements MyConfig {
public double getWeightOfBomb() {
return MyConfiguration.getInstance().getWeightOfBomb();
}
}
If you use a DI framework, just setup you classes to have your MyConfig implementation injected. If you don't, then the laziest approach that still has all the benefits is to do something like:
class SomeClass {
private MyConfig myConfig = new MyConfigImpl();
}
Really it's up to you. The important thing is that you can replace myConfig on a per instance basis when you later realize that you need the behavior to vary and/or for unit testing.
You could create an interface to represent the configuration:
public interface Config {
interface Key {}
String get(Key key);
String get(Key key, String defaultValue);
}
And a singleton implementation:
public enum MyConfig implements Config {
INSTANCE("/config.properties");
private final Properties config;
MyConfig(String path) {
config = new Properties();
try {
config.load(this.getClass().getResourceAsStream(path));
} catch (IOException | NullPointerException e) {
throw new ExceptionInInitializerError(e);
}
}
#Override
public String get(Config.Key key){
return config.getProperty(key.toString());
}
#Override
public String get(Config.Key key, String defaultValue) {
return config.getProperty(key.toString(), defaultValue);
}
public enum Key implements Config.Key {
PROXY_HOST("proxy.host"),
PROXY_PORT("proxy.port");
private final String name;
Key(String name) { this.name = name; }
#Override
public String toString() { return name; }
}
}
And then inject the configuration in your classes:
public class SomeClass {
private final Config config;
public SomeClass(Config config) {
this.config = config;
}
public void someMethod() {
String host = config.get(Key.PROXY_HOST);
String port = config.get(Key.PROXY_PORT, "8080");
// Do something
}
}
Additional proposal for noah's answer.
If it is inconvenient for you to write a method for each configuration parameter, then you could use enum for that. Here is what I mean:
public class Configuration {
private final Properties properties;
public enum Parameter {
MY_PARAMETER1("my.parameter1", "value1"),
MY_PARAMETER2("my.parameter2", "value2");
private final String name;
private final String defaultValue;
private Parameter(String name, String defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
}
private String getName() {
return name;
}
private String getDefaultValue() {
return defaultValue;
}
}
public Configuration(Properties properties) {
this.properties = (Properties)properties.clone();
}
//single method for every configuration parameter
public String get(Parameter param) {
return properties.getProperty(param.getName(), param.getDefaultValue());
}
}
After that, if you have a new configuration parameter, all you need to do is to add a new enum entry.
You can also extract an interface from Configuration class, of course, moving enum outside.

Using Spring IoC to set up enum values

Is there a way to set up such enum values via Spring IoC at construction time?
What I would like to do is to inject, at class load time, values that are hard-coded in the code snippet below:
public enum Car
{
NANO ("Very Cheap", "India"),
MERCEDES ("Expensive", "Germany"),
FERRARI ("Very Expensive", "Italy");
public final String cost;
public final String madeIn;
Car(String cost, String madeIn)
{
this.cost= cost;
this.madeIn= madeIn;
}
}
Let's say that the application must be deployed in Germany, where Nanos are "Nearly free", or in India where Ferraris are "Unaffordable". In both countries, there are only three cars (deterministic set), no more no less, hence an enum, but their "inner" values may differ. So, this is a case of contextual initialization of immutables.
Do you mean setting up the enum itself?
I don't think that's possible. You cannot instantiate enums because they have a static nature. So I think that Spring IoC can't create enums as well.
On the other hand, if you need to set initialize something with a enum please check out the Spring IoC chapter. (search for enum) There's a simple example that you can use.
I don't think it can be done from Spring's ApplicationContext configuration. But, do you really need it done by Spring, or can you settle for simple externalization using ResourceBundle; like this:
public enum Car
{
NANO,
MERCEDES,
FERRARI;
public final String cost;
public final String madeIn;
Car()
{
this.cost = BUNDLE.getString("Car." + name() + ".cost");
this.madeIn = BUNDLE.getString("Car." + name() + ".madeIn");
}
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(...);
}
In the properties file, one for each specific locale, enter the keys describing the possible internal enum values:
Car.NANO.cost=Very cheap
Car.NANO.madeIn=India
Car.MERCEDES.cost=Expensive
...
The only drawback of this approach is having to repeat the name of enum fields (cost, madeIn) in Java code as strings. Edit: And on the plus side, you can stack all properties of all enums into one properties file per language/locale.
OK, it's quite fiddly, but it CAN be done.
It's true that Spring cannot instantiate enums. But that's not a problem - Spring can also use factory methods.
This is the key component:
public class EnumAutowiringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private final List<Class<? extends Enum>> enumClasses = new ArrayList<>();
public EnumAutowiringBeanFactoryPostProcessor(Class<? extends Enum>... enumClasses) {
Collections.addAll(this.enumClasses, enumClasses);
}
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (Class<? extends Enum> enumClass : enumClasses) {
for (Enum enumVal : enumClass.getEnumConstants()) {
BeanDefinition def = new AnnotatedGenericBeanDefinition(enumClass);
def.setBeanClassName(enumClass.getName());
def.setFactoryMethodName("valueOf");
def.getConstructorArgumentValues().addGenericArgumentValue(enumVal.name());
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(enumClass.getName() + "." + enumVal.name(), def);
}
}
}
}
Then the following test class shows that it works:
#Test
public class AutowiringEnumTest {
public void shouldAutowireEnum() {
new AnnotationConfigApplicationContext(MyConig.class);
assertEquals(AutowiredEnum.ONE.myClass.field, "fooBar");
assertEquals(AutowiredEnum.TWO.myClass.field, "fooBar");
assertEquals(AutowiredEnum.THREE.myClass.field, "fooBar");
}
#Configuration
public static class MyConig {
#Bean
public MyClass myObject() {
return new MyClass("fooBar");
}
#Bean
public BeanFactoryPostProcessor postProcessor() {
return new EnumAutowiringBeanFactoryPostProcessor(AutowiredEnum.class);
}
}
public enum AutowiredEnum {
ONE,
TWO,
THREE;
#Resource
private MyClass myClass;
}
public static class MyClass {
private final String field;
public MyClass(String field) {
this.field = field;
}
}
}
Why not provide a setter (or constructor argument) that takes a String, and simply call Enum.valueOf(String s) to convert from a String to an enum. Note an exception will get thrown if this fails, and your Spring initialisation will bail out.
You can't create new enum values via Spring, they must be declared in the class. However, since the enum values will be singletons anyway (created by the JVM), any configurations that should be set, or services to be injected, can be done via invoking static methods in the enum class:
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/config/MethodInvokingFactoryBean.html
I have done it in the following way:
#Component
public class MessageSourceHelper {
#Inject
public MessageSource injectedMessageSource;
public static MessageSource messageSource;
public static String getMessage(String messageKey, Object[] arguments, Locale locale) {
return messageSource.getMessage(messageKey, arguments, locale);
}
#PostConstruct
public void postConstruct() {
messageSource = injectedMessageSource;
}
}
That way you can easily use it in the enum to get messages in the following way:
MessageSourceHelper.getMessage(key, arguments, locale);
I have faced the same issue when I was working to localize my enum label in different locales.
Enum Code:
public enum Type {
SINGLE("type.single_entry"),
MULTIPLE("type.multiple_entry"),
String label;
Type(String label) {
this.label = label;
}
public String getLabel() {
String translatedString = I18NTranslator.getI18NValue(getLocale(), label);
return StringUtils.isEmpty(translatedString) ? label : translatedString;
}
}
My I18NTranslator class which basically load the message source to get localized content. I18Ntransalator class depends on springContext if you don't write you might face a peculiar bug. Some time might face a dependency related which causes null pointer exception. I had put a lot of effort to resolve this issue.
#Component
#DependsOn({"springContext"})
public class I18NTranslator {
private static MessageSource i18nMessageSource;
public static String getI18NValue(Locale locale, String key) {
if (i18nMessageSource != null)
return i18nMessageSource.getMessage(key, null, locale);
return key;
}
#PostConstruct
public void initialize() {
i18nMessageSource = SpringContext.getBean("i18nMessageSource", MessageSource.class);
}
}
We have to set the spring context
#Component
#Slf4j
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
public static <T extends Object> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
public static <T extends Object> T getBean(String beanClassName, Class<T> beanClass) {
return context.getBean(beanClassName, beanClass);
}
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
SpringContext.context = context;
}
}
Now it is time to define the bean for I18NMessageSource.
#Configuration
public class LocaleConfiguration implements WebMvcConfigurer {
#Bean(name = "i18nMessageSource")
public MessageSource getMessageResource() {
ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
messageResource.setBasename("classpath:i18n/messages");
messageResource.setCacheSeconds(3600);
messageResource.setDefaultEncoding("UTF-8");
return messageResource;
}
#Bean(name = "localeResolver")
public LocaleResolver getLocaleResolver() {
return new UrlLocaleResolver();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
//UrlLocalInterceptor is custom locale resolver based on header paramter.
UrlLocaleInterceptor localeInterceptor = new UrlLocaleInterceptor();
registry.addInterceptor(localeInterceptor);
}
}
PS: if you need the custom interceptor code I can share in the comment.
Defines all local properties files inside resources/i18n folder with messages prefix like messages_en.properties for english and messages_fr.properties fro french.
What do you need to set up? The values are created when the class loads, and as it's an enum, no other values can be created (unless you add them to the source and recompile).
That's the point of an enum, to be able to give limit a type to an explicit range of constant, immutable values. Now, anywhere in your code, you can refer to a type Car, or its values, Car.NANO, Car.MERCEDES, etc.
If, on the other hand, you have a set of values that isn't an explicit range, and you want to be able to create arbitrary objects of this type, you'd use the same ctor as in your post, but as a regular, not enum class. Then Spring provides various helper clases to read values from some source (XML file, config file, whatever) and create Lists of that type.
<bean id="car" class="Foo">
<property name="carString" value="NANO" />
</bean>
And then in your class Foo, you would have this setter:
public void setCar(String carString) {
this.carString = Car.valueOf(carString);
}
Attempting to mutate an Enum is well silly and goes completely against their design objectives. An enum by definition represents a distinct value within a group. If you ever need more / less values you will need to update the source. While you can change an enums state by adding setters (after all they are just objects) your hacking the system.
All right, this is a bit complex but you may find a way to integrate it. Enums are not meant to change at runtime, so this is a reflection hack. Sorry I don't have the Spring implementation part, but you could just build a bean to take in the enum class or object, and another field that would be the new value or values.
Constructor con = MyEnum.class.getDeclaredConstructors()[0];
Method[] methods = con.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals("acquireConstructorAccessor")) {
m.setAccessible(true);
m.invoke(con, new Object[0]);
}
}
Field[] fields = con.getClass().getDeclaredFields();
Object ca = null;
for (Field f : fields) {
if (f.getName().equals("constructorAccessor")) {
f.setAccessible(true);
ca = f.get(con);
}
}
Method m = ca.getClass().getMethod(
"newInstance", new Class[] { Object[].class });
m.setAccessible(true);
MyEnum v = (MyEnum) m.invoke(ca, new Object[] {
new Object[] { "MY_NEW_ENUM_VALUE", Integer.MAX_VALUE } });
System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());
This is taken from this site.
Here is the solution I came to (thanks to Javashlook whose answer put me on track). It works, but it's most probably not a production-grade way of doing it.
But better than a thousand words, here is the code, I'll let you judge by yourself.
Let's take a look at the revised Car enum :
public enum Car {
NANO(CarEnumerationInitializer.getNANO()), MERCEDES(
CarEnumerationInitializer.getMERCEDES()), FERRARI(
CarEnumerationInitializer.getFERRARI());
public final String cost;
public final String madeIn;
Car(ICarProperties properties) {
this.cost = properties.getCost();
this.madeIn = properties.getMadeIn();
}
}
And here are the "plumbling" classes :
//Car's properties placeholder interface ...
public interface ICarProperties {
public String getMadeIn();
public String getCost();
}
//... and its implementation
public class CarProperties implements ICarProperties {
public final String cost;
public final String madeIn;
public CarProperties(String cost, String madeIn) {
this.cost = cost;
this.madeIn = madeIn;
}
#Override
public String getCost() {
return this.cost;
}
#Override
public String getMadeIn() {
return this.madeIn;
}
}
//Singleton that will be provide Car's properties, that will be defined at applicationContext loading.
public final class CarEnumerationInitializer {
private static CarEnumerationInitializer INSTANCE;
private static ICarProperties NANO;
private static ICarProperties MERCEDES;
private static ICarProperties FERRARI;
private CarEnumerationInitializer(ICarProperties nano,
ICarProperties mercedes, ICarProperties ferrari) {
CarEnumerationInitializer.NANO = nano;
CarEnumerationInitializer.MERCEDES = mercedes;
CarEnumerationInitializer.FERRARI = ferrari;
}
public static void forbidInvocationOnUnsetInitializer() {
if (CarEnumerationInitializer.INSTANCE == null) {
throw new IllegalStateException(CarEnumerationInitializer.class
.getName()
+ " unset.");
}
}
public static CarEnumerationInitializer build(CarProperties nano,
CarProperties mercedes, CarProperties ferrari) {
if (CarEnumerationInitializer.INSTANCE == null) {
CarEnumerationInitializer.INSTANCE = new CarEnumerationInitializer(
nano, mercedes, ferrari);
}
return CarEnumerationInitializer.INSTANCE;
}
public static ICarProperties getNANO() {
forbidInvocationOnUnsetInitializer();
return NANO;
}
public static ICarProperties getMERCEDES() {
forbidInvocationOnUnsetInitializer();
return MERCEDES;
}
public static ICarProperties getFERRARI() {
forbidInvocationOnUnsetInitializer();
return FERRARI;
}
}
Finally, the applicationContext definition :
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="nano" class="be.vinkolat.poc.core.car.CarProperties">
<constructor-arg type="java.lang.String" value="Cheap"></constructor-arg>
<constructor-arg type="java.lang.String" value="India"></constructor-arg>
</bean>
<bean id="mercedes"
class="be.vinkolat.poc.core.car.CarProperties">
<constructor-arg type="java.lang.String" value="Expensive"></constructor-arg>
<constructor-arg type="java.lang.String" value="Germany"></constructor-arg>
</bean>
<bean id="ferrari" class="be.vinkolat.poc.core.car.CarProperties">
<constructor-arg type="java.lang.String"
value="Very Expensive">
</constructor-arg>
<constructor-arg type="java.lang.String" value="Italy"></constructor-arg>
</bean>
<bean id="carInitializer"
class="be.vinkolat.poc.core.car.CarEnumerationInitializer"
factory-method="build" lazy-init="false">
<constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
ref="nano" />
<constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
ref="mercedes" />
<constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
ref="ferrari" />
</bean>
</beans>
It works, but there is one major weakness : CarEnumerationInitializer MUST be instantiated BEFORE any reference is made to Car enumeration, otherwise CarProperties are null, meaning that Car's properties can't be set when Car is loaded (hence the IllegalStateException thrown, to at least make it crashes in a predictable and documentated way). carInitializer bean's property lazy-init set to an explicit false, to put emphasis on the need to load it as soon as possible.
I would say it may be useful in a simple application, one where you can easely guess where a first call to Car will be made. For a larger one, it will probably be such a clutter that I didn't encourage you to use it.
Hope this help, comments and vote (up and down) very welcome :) I'll wait for a few days to make this one the accepted answer, to let you react.
You can use Enum class as factory bean. Example: setting serializationInclusion field with enum value:
<property name="serializationInclusion">
<bean class="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion" factory-method="valueOf">
<constructor-arg>
<value>NON_NULL</value>
</constructor-arg>
</bean>
</property>
But actually (Spring 3.1) a simpler solution works: you just write the enum value and Spring recognizes what to do:
<property name="serializationInclusion" value="NON_NULL"/>

Categories

Resources