sábado 5 de enero de 2008

Squashing boilerplate in Spring

Nobody can deny that the advent of IoC/DI frameworks, ORM tools and Web Services has brought robustness to the enterprise world. Programs are more clear and concise than ever before, at the cost of moving configuration from the source code to a specific realm, usually based on XML files. This, by itself, is not bad at all. In fact, is a Good Thing. Problems appear when the configuration is a language itself and grows so much that can be compared in size to the source code.

Here's a little guide that will help you to minimize the amount of config needed in a project
  • Annotations are your friend!
    Easy one. From a dubious start, annotations are now considered a first class citizen. Even Spring developers encourage their use now. If you are using Java5+ try to move as much XML to annotations. It will help you in two ways: less code is needed and configuration is attached to the component directly (which makes reading code easier).

    In Hibernate/JPA nearly everything can be expressed with an annotation. Spring now offers annotations for bean creation(@Component...), managing life cycles(@PostConstruct...), wiring dependencies (@Resource...) and security (@Secured...). The MVC framework (in 2.5) also packs some more to help with controllers (@Controller...) and method and parameter mappings(@RequestMapping...).

  • Leverage the latest version
    One of the areas that has evolved more positively from Spring 1.x, without doubt, is writing configuration XML. The second release of Spring brought a lot of syntax sugar in the form of additional schemes(jee, util,...) and simplified the dependency declaration. Spring 2.5 has brought the p namespace and component scanning. And above all, not only is XML configuration easier to write, it is now also extensible.

  • Autowire
    Autowire has always been available and has been discouraged with passion as well. Detractors will tell you to skip the magic that happens behind the curtain. I cannot agree more. It was a common point of failure. And one difficult to debug.

    Nonetheless, the situation now has changed a little. The @Autowired annotation is already quite clear and it can be used in conjunction with @Qualifier to improve the understanding. I wouldn't autowire everything, don't get me wrong, but how many times do you have an interface with just a default implementation? Not all your beans can be candidate to be replaced by another strategy, do they?

  • Convention over configuration
    A mantra for RoR developers. Probably they embraced it after writing some code in Java! Basically, avoid configuring something if there's a suitable default value already. And stick to defaults as much as possible. Maven does it for example, keep the standard directory structure and Maven can work with pretty little configuration overhead.

    Spring has always favored this kind of development as well. But in 2.x MVC new additions encourage it further(it's called sensible defaulting): ControllerClassNameHandlerMapping and DefaultRequestToViewNameTranslator. In case you haven't used them yet, they allow the dispatcher servlet to select a handler based on the class name of the controller and equally forward the result to a view. For example, IndexController and index.jsp would be invoked for http://.../index.htm without any configuration explicitly written.

    Of course, beware that there's again a lot of magic behind the curtain. At least document it somewhere (the project wiki comes to my mind). It won't cause you any troubles though (if you're not pushing the edges..), the controller and the view will be invoked or not

  • Create a root application context
    Beans can be inherited from a parent application context in Spring. This means that any shared beans should be refactored there and later be referenced from any other context. Beans can be shared between web applications, EJBs and the like. More info is available here. Remember that Spring 2.5 offers the possibility of deploying application contexts as a JCA adapter for headless applications.

  • Create abstract beans
    Probably you're already using abstract classes to encapsultae common functinality. Are you doing the same for beans? I'll copy Spring documentation here:
    A bean definition potentially contains a large amount of configuration information, including container specific information (i.e. initialization method, static factory method name, etc.) and constructor arguments and property values. A child bean definition is a bean definition which inherits configuration data from a parent definition. It is then able to override some values, or add others, as needed. Using parent and child bean definitions can potentially save a lot of typing. Effectively, this is a form of templating.
    If you're still in doubt imagine how many of your beans usually have a dependency on the persistence facade, the document repository, a cipher or a combination of them! A hierarchy of bean skeletons helps immensely (and not only in writing less code).

  • Less is more
    If you've read Getting Real from 37 Signals (it's free and highly recommended!) you're familiar with the term. If you've read The Pragmatic Programmer you are intimate with the DRY (Don't Repeat Yourself!) principle by now. Maybe Martin Fowler Refactoring? Pick the example you like most, rest assured there are several. All point in the same direction, write less, more concise code. It'll be easier to read, to debug, to maintain and generally it'll work better. The moral is to abandon all complexity!

1 comentarios:

djo.mos dijo...

Hi.
Nice compilation. Really.
Just to mention that the Spring Controller stereotype is not limited to Spring MVC, and can be used in JSF for instance.

Regards.