I would say that the reason Spring favors XML over Java is that the two languages ββare for two different tasks. Java is a programming language. Its purpose is to describe algorithms, programs, control flow, etc. If the output of your program structure requires a complex control flow, Java would be a good choice.
XML is fundamentally different. This is not a programming language. This is a way of describing ordered data, such as a cookbook or vector graphics. If the organization and interdependencies of your software system are static values, then XML may be the right place to host them.
I would say that your configuration files, as a rule, should not be in Java for the same reason that the cookbook should not be in Java. In fact, I could do the same conversion:
<book> <chapter>It was the best of times, it was the worst of times</chapter> </book> public static void main(String[] args) { String chapter1 = BookXMLParser.loadChapter(1); System.out.println(chapter1); }
obviously, can also be done entirely in Java:
public static void main(String[] args) { String chapter1 = "It was the best of times, it was the worst of times"); System.out.println(chapter1); }
Now, obviously, this is a ridiculous example. Books are hundreds of pages. It would be foolish to keep them in Java code. However, I would make the same argument for the Spring configuration. One of my biggest programs has Spring XML, which has many thousands of lines.
Of course, there is something that can be said in favor of defining this material in Java. In particular, the IDEs could more easily provide additional help about which classes use what other static analysis tools would do a little better analysis of your code for problems.
Then again there are some disadvantages. Giving you this configuration in Java allows the programmer to do all sorts of unpleasant things that are much more difficult to achieve in XML, for example:
bean1.setName("fred"); if( System.currentTimeMillis() > 1234567890l ) { //Automatically use new feature after next Thursday bean1.setNewFeature(1); } else if( x > 17 ) { switch(y) { case POTATO: bean1.setNewFeature(0); break; case POTAHTO: bean1.setNewFeature(1); case WHO_COULD_ASK_FOR_ANYTHING_MORE_FALLTHROUGH: bean1.setFoo(bar); break; default: baz? bean1.setBar(baz) : if(17 > t) { bean1.setNewFeature(q) } else { throw new RuntimeException("That odd..."); } } }
Ok, you understand. Your code obviously won't start so badly, but you will be tempted to use some if expression, and then you will use another and then another.