Reputation: 105
I have a requirement to initialize the "flag" field in a java enum by spring:
public enum EntitySequenceType {
TypeOne(-1),
TypeTwo(-1000);
private boolean flag;
EntitySequenceType(long firstId){
System.out.println("enum's constructor: "+this.name()+" firstId="+firstId);
}
public void setFlag(boolean val) {
this.flag = val;
}
public boolean getFlag() {
return this.flag;
}
}
The spring config is:
<bean id="myEnum" class="com.maven.start.maven_spring.EntitySequenceType"
factory-method="valueOf">
<property name="flag" value="true"/>
<constructor-arg>
<value>TypeOne</value>
</constructor-arg>
</bean>
But I have met some problems, so I have the following questions:
1.It seems that I can only write a single value in the <constructor-arg>
tag in the config xml, I can't figure out why it is like this.
2.When I debugging the code, I found that when spring is initializing the bean, although I only write one constructor-arg
value in the config xml, the constructor is called twice.How could this happen?
3.In the constructor of EntitySequenceType, I found that the "flag"'s value is null, why? There is "afterPropertiesSet()" can be called if the enum implements InitializingBean, but it is not called every time a enum type is constructed, so is there any method to be called after the field is set by spring, but is called every time a enum type is called?
Thanks for your answers!
Upvotes: 2
Views: 2596
Reputation: 280112
It seems that I can only write a single value in the tag in the config xml, I can't figure out why it is like this.
Used with a factory-method
, the constructor-arg
values are referring to the parameter list of that factory-method
. EntitySequenceType.valueOf(String)
only takes one argument, a String
.
When I debugging the code, I found that when spring is initializing the bean, although I only write one constructor-arg value in the config xml, the constructor is called twice.How could this happen?
Enum types, like any other types, have their .class
file loaded and initialized when they are first referenced in the code. The enum
constants
TypeOne(-1),
TypeTwo(-1000);
are actually static
fields in the compiled byte code. As such, they are initialized when the class is initialized. Those are two constructor calls, so that is what you see.
The constructor-arg
value has nothing to do with these constructors, it has to do with your factory-method
.
In the constructor of EntitySequenceType, I found that the "flag"'s value is null, why? There is "afterPropertiesSet()" can be called if the enum implements InitializingBean, but it is not called every time a enum type is constructed, so is there any method to be called after the field is set by spring, but is called every time a enum type is called?
It can't be null
, it's a primitive type. Your property is going to be set after the factory-method
is called and executed. There is no need to implement InitializingBean
.
Don't use an enum
for this. Enums are meant to be constant.
Upvotes: 1
Reputation: 42040
The problem is:
The constructor for an enum type must be package-private or private access. It automatically creates the constants that are defined at the beginning of the enum body. You cannot invoke an enum constructor yourself.
Upvotes: 1