views:

199

answers:

4

I'm working on an Spring application which has a large number of beans - in the hundreds - and it's getting quite cumbersome to use and document.

I'm interested in any experience you have with DI-enabled apps with a large number of beans which would aid maintainability, documentation and general usage.

Although the application is Spring-based with a couple of context files, I'm open to listening about suggestions regarding any DI container and about DI in general as well.

+5  A: 

I found the following to be of use:

  1. split your Spring configurations into multiple standalone configurations, and use Spring's import facility to import configuration dependencies (see here, section 3.2.2.1). That way you have a set of configurations that you can combine or disassemble as required, and they are all self-dependent (all the dependencies will be explicit and referenced)
  2. Use an IDE that is Spring-aware, and allows you to navigate through the configurations via point-n-click on beans (references/names, to-and-from source code). Intellij works very well at this (version 7 and beyond, I think). I suspect Eclipse would do something similar.
  3. Revise what you're injecting where. You may want to refactor multiple bean injections into one composite or 'meta' bean, or a larger component. Or you may find that components you once thought you'd need to inject have never changed, or never demanded that injectability (for testing, implementing as strategies etc.)

I used to work with a huge Spring installation, with hundreds (thousands?) of beans. Splitting the configurations up made life a lot more manageable, and simplified testing/creating standalone processes etc. But I think the Intellij Spring integration that came with Intellij made the most difference. Having a Spring-aware IDE is a major timesaver.

Brian Agnew
+1 - Very good advice. IntelliJ recommendation alone is worth it.
duffymo
Thanks for the answer. What criteria do you split your beans in files on? Module/concern/something else? I'm already using Spring IDE for Eclipse which is quite good. The refactoring bit is also nice.
Robert Munteanu
Related functionality. The project I worked on consisted of many standalone programs running off the same codebase, so division was quite easy. But a hierarchical pattern works well, and allows testing of related components within the same config etc.
Brian Agnew
+5  A: 
Wilson Freitas
Thanks for the answer. Autowiring does reduce the code, but how do you insure that you retain the overall picture? Do you still easily see what goes where?
Robert Munteanu
I agree this is a challenge and I believe there not an easy solution. I think a good design is the key to keep spring managed beans under control. Naming standards for packages and classes can help. Of course it is possible to use JMX and bean post processors to create some kind of management console but I've never tried this :)
Wilson Freitas
+3  A: 

As @Wilson Freitas says, use autowiring. I daily work with a system that has few thousand spring managed beans using mostly autowired. But I think the notion of "retaining the overall picture" is slightly misplaced. As a system grows you can't expect to do that in the same way as you did on a smaller system. Using @Autowiring forces you to use stronger typing than xml-based spring, which again means you can use the dependency tracking features of your IDE to navigate in dependencies.

I really think it's suboptimal to think that you need to understand too much of the "full" picture when it comes to the spring configuration. You should be focusing on your code and it's dependencies. Managebility and maintainability are achieved by organizing this code well, naming things well and managing your coupling; all of the stuff that applies even if you're not using spring. Spring shouldn't change much, and with the approval of JSR-330, it may even seem like dependency injection will creep further "under the hood" of the runtime environment.

krosenvold
+1  A: 

Our strategy is:

  • naming conventions, e.g.: fooService, fooDao, fooController;
  • property setters following these conventions;
  • autowiring by name (autowire="byName"); we had many problems with autowiring by type, especially on the controller layer
Megadix