This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

How does really work bean initialization???

Feb 25th, 2006, 06:33 PM

Dear members,

I have a bean propertiesManager for defining the properties of my project, so I want to use this bean in order to get some constant values on other beans. I am setting the lazy-init to false in order to have the garantee this bean will be first instanciated.

so, even using lazy-init and depends-on to force that really propertiesManager bean has to be initialized before, that doesn't happen. I am for sure loosing somthing, but I guess it should be a way to do make this kind of dependence.

I am planning to convert PropertiesManager into class with static method and attributes, but I don't know if this is a good desing and if it works.

When your positionBatch bean is initialized it get constructed first and then the setters get called. So your field initializer code is being executed when the object is being constructed, but before the bean properties have been set. That is why the propertiesManager property of you bean is null even though it has been created.

Have you looked at the PropertyPlaceHolderConfigurer? That seems like it does what you are looking for.

Comment

Thanks for your interest on my problem. The reason is what you have said, but it is hard for me to understand. The propertiesManager bean is a singleton, and have to be instanciated first because it is not lazy and the positionBatch bean depends on this bean, so when I want to initialize positionBatch bean, the propertiesManager bean should be instanciated before and it is a singleton, so it should take this, but it doesn't happen because the rare call back mechanism on the bean initialization process.

About your suggestion using PropertyPlaceHolderConfigurer, I think it is for different purpose. This implementation allow you to define properties in the Ant way, that is: ${property}, so it looks on the property file and replace this token by its value on the applicationContext.xml file. Using this solution, you have add a property definition on the positionBatch definition in order to set it current value. If you want to share this property by other class you have to add this property on all possible bean definition.

The idea behind the PropertiesManager is to have on ONE PLACE all possible project definitions (I am implemeting a batch process, so I have to controll a lot or parameters), in such way that you can define the default properties of the project on the lra.properties file and for a particular build or just for working in a team you can define your lra_testCustom.properties, that overrides the default definition of the properties. So the lra.properties and the applicationContext.properties are more control version stable. That is my idea.

Now I guess I explained more my problem, please let me know if you have any other suggestion about this.

Thanks in advance,

Comment

I agree with dgynn, its the field initialization which comes before the setter injection. To experiment you can move the field init into an actual initialization method which would get invoked in the 'afterPropertiesSet' lifecycle stage, for example:

Comment

I agree with dgynn, its the field initialization which comes before the setter injection. To experiment you can move the field init into an actual initialization method which would get invoked in the 'afterPropertiesSet' lifecycle stage, for example:

And then change your abstract class's propertiesManager to a java.util.Properties object. Properties in the second file will override properties in the first file.

That was my first approach, but I have found two problems:
- The toString() method for Properties, doesn't separate the information
between default properties (new Properties(properties)) and the current properties.
- Before setting the default and current properties, I need to parse some values for considering the spetial case when a property value represents
the system property, for example if my tmp.dir has the value java.io.tmpdir.
I want the property tmp.dir stores the value of java.io.tmpdir, that is the
result of: System.getProperty("java.io.tmpdir"). Any way I will try to check this point again, probably I did some mistake.

Also, you might want to consider an abstract bean definition if you are going to have multiple beans that access the properties manager.

About your second suggestion, I took into account, but just for simplify the
sample code, I have omitted it, thank any way.

so the bean propertiesManager, is a singleton and with lazy-init=false (it is not really necessary)

Now I have changed the definition of the class PropertiesManager, now the defaultProperties and propertieswill be static, with setter method non static, because otherwise the bean initialization doesn't work.

And then change your abstract class's propertiesManager to a java.util.Properties object. Properties in the second file will override properties in the first file.

I prefer to use delegation with the Properties because I would like to add some additional behaviour, I am planning to add getIntProperty, getBoolProperty, getFileProperty, for example. At this point a possible solution would be to extends the Properties, but I don't know exactly how to use your solution with this. Any way I am going to think about that.

Thanks,

Comment

I have a LocalizedString bean in applicationContext.xml and I am setting a boolean variable(dealerSites) through applicationContext.xml and there is a map variable (values) in my class LocalizedString.

Now, the setter is called after schema update while map variable is being accessed in sessionFactory itself (via a call to getValues function), in which the value of dealersites is being assumed false.

As can be seen from the code, i want Map to be lazily loaded when dealerSites is true, which is not happening.

What is to be done? (I am attaching the code, name of file is - LocalizedString.java)

Comment

There is not Spring-specific in this case. It behaves like any other Java application. First object is created with appropriate constructor (even if object is created by factory method somewhere in that method constructor shall be called!) and all object fields are initialized by JVM according to Java Language Specification.
It means that all fields of non-primitive that have no explicit initializers and are not initialized by constructor are set to null, numeric fields to 0, boolean to false etc.

Comment

But then as I checked in log - getValues method being called in AbstractEntityPersister by Dealers.java (another class). Whereas setter being called after that.
And there (in AbstractEntityPersister) map object being accessed assuming the value of boolean variable to be false.

I am attaching the code(LocalizedString.java) to make the point clear.

Thanks,
Sucheta.

Comment

But then as I checked in log - getValues method being called in AbstractEntityPersister by Dealers.java (another class). Whereas setter being called after that.
And there (in AbstractEntityPersister) map object being accessed assuming the value of boolean variable to be false.

I am attaching the code(LocalizedString.java) to make the point clear.