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.

A general best practice for any problems is, "read the reference manual". So many of the simple questions can be answered by having a quick thumb through it. We are ALL still learning and obviously there are times you can't find the answer in there, but atleast give it a go! Please .

Personally, I don't use it. I agree with a lot of your points. The few times I have used it, people really didn't like it. They wanted to know where the beans were coming from. As I said previously, I'm glad its there, but it is voodoo.

To limit the risk of an accidental bean overwrite.A short true story:
A project used XFire. (XFire is a SOAP framework with Spring support, see http://xfire.codehaus.org/ for more information). The project named a bean of the type org.springframework.beans.factory.config.CustomEdi torConfigurer CustomEditorConfigurer. They got weird errors. The reason of these errors was… XFire also named a bean CustomEditorConfigurer. And this XFire CustomEditorConfigurer bean had overwritten the CustomEditorConfigurer bean of the project.

Last edited by Ward Bergmans; Dec 21st, 2006, 03:42 AM.
Reason: Added an argument: To limit the risk of an accidental bean overwrite.

Comment

Is there any best practice on using aliases for switching between different environments?

Place the parts of your configuration that may change in different environments in (a) separate xml file(s).

Make a version of this file for every different environment. (And give this file a describing name ;-).)

Category: Spring core – configuration

Argumentation:

Then the configuration part that doesn’t change in different environments is guaranteed not to change. So the bulk of your configuration can be tested outside the eventual deployment environment.

The separation makes clear which parts of the configuration change over the different environments. So which parts need special test attention after the application is deployed in a new environment.

If you make configurations for every different environment with all the beans (those beans that change and those that stay the same) in it, then you get configuration duplication. The beans that stay the same will be defined in all the configuration files for the different environments.

If you make one configuration file with the configuration for every different environment and comment out the configuration parts that you don’t need in that environment, then you will get the following problems:

If you have this situation: you comment out the configuration for the other environments and uncomment the configuration to test locally. You start coding new functionality. You edit the configuration for this new functionality. You code a little more till everything works.
Then you synchronize your code with the versioning system. You don’t check in your configuration, because you don’t want to commit the changes that you’ve made to test locally ...but you forgot that the configuration also had changes to make the new functionality working. You build and deploy your application. And you’ve got a bug...
Or:
Then you synchronize your code with the versioning system. You check in all the modified files. ...but you forgot that the configuration file contains the configuration to test locally instead of the original configuration. You build and deploy your application. And you’ve got a bug...

Configuration files will get very long and hard to read and maintain.

It isn’t easy to comment out configuration parts that have comments in them.

If you would not place this user dependent configuration in a separate file, then this can happen:

Developer 1 checks out code from the versioning system.

Developer 1 changes the user dependent part of the configuration to be able to test the application locally.

Developer 1 starts coding. And after a while he adds something to the configuration. He does some more coding. And all the test succeed :-)

Developer 1 checks in all the code and configuration (including the user dependent part).

Developer 2 synchronizes his code.

Developer 2 will get a merge conflict on the configuration file.

This causes the following problems:

Time is wasted, because merge conflicts need to be solved.

It can easier happen that the user dependent configuration of a certain developer gets checked in the versioning system. And all the “type_your_data_here” notes will be overwritten.

Even worse, this can happen:

Steps 1-3 from above are preformed.

Developer 1 checks in all the code, but he doesn’t check in the configuration, because he thinks “that file contains my user dependent configuration. I don’t want to place that in the versioning system, so I skip that file”

This causes the following problems:

The new configuration part isn’t backed up in the versioning system.

The application won’t work anymore, because the new part of the configuration is missing.

I wouldn't agree with this, I would use a PropertyPlaceholderConfigurer and move the configuration out to a properties file. You can also then tell the configurer that if the value can't be resolved to throw an exception.

public void setIgnoreUnresolvablePlaceholders(boolean ignoreUnresolvablePlaceholders)
Set whether to ignore unresolvable placeholders. Default is "false": An exception will be thrown if a placeholder cannot be resolved.

Comment

Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser will issue an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors are early as possible) if the target bean is in the same XML file.

I do not really get why this is advised.
I see 2 disadvantages of working with the local attribute:
1. increases clutter since there is no shortcut form for the ref local;

Code:

<property name="prop" ref="someBean />

would have to be rewritten as:

Code:

<property name="prop">
<ref local="someBean"/>
</property>

2. when the decision is made to split up 1 xml config file into 2 or more then it's possible that a lot of these local refs will have to be rewritten as 'normal' ref's.

Comment

Use constructor injection for properties that must be set in a certain order.

Only provide (a) constructor(s) that guarantee(s) that the properties are set in the required order.

Category: Spring core

Argumentation:

If properties must be set in a certain order, you would normally design you class like this: the class will only have constructors that make sure the properties are set in the right order.
Why would you change that design when you use the Spring framework???
The whole idea behind Spring is that you can design your classes how you like and have Spring work for you, not the other way around.

Even if you have this requirement of setting properties in a specific order, why not defer the logic which processes the values to an init method, invoked after the object has been constructed / injected? I prefer using setters over constructor args, as it leads to far more legible configuration files (you cant specify constructor args by name). Using the init method approach allows a greater degree of flexibility for clients to configure an object before its use, and you can (and should) use assertions in that method to ensure that required properties have been set (there is also an annotation-based approach for required-ness in the lastest couple versions of Spring, I believe). And you dont have to tie yourself to Spring by implementing InitializingBean, since you can explicitly name the method to invoke post-injection.

What I usually do to ease unit testing is to create both a default constructor and one which takes all of my required properties; the latter invokes the init method after setting the values. This leads to APIs which are accessible within and without the Spring context.

One argument for constructor injection I suppose would be in the case of immutable objects, but if clients code to interfaces instead of implementations, the setters are hidden anyways.