Java Moods

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Thursday, 17 September 2009

Spring: Use Custom Namespaces!

Posted on 23:30 by Unknown

Have you ever heard of custom XML namespaces for Spring? I know you love Spring (like I do), so... probably yes. They are available since Spring 2.0 which came out October 2006, so I just can't believe we didn't use them up to now.

The Old-Fashioned Way

Well, we are building our web apps on JSF and Spring Web Flow, and additionally use a custom framework for adding a few more features like mapping between business objects and view objects based on XML mapping descriptions. Of course, this framework part is designed "IoC friendly", i.e. it's based on interfaces and standard implementations that need to be plugged by Spring configuration.

We did this by providing a basic Spring configuration that defines defaults for most elements and injects all required references into the main configuration objects. To allow the project to provide custom implementations, this code relies on particular bean names that have to be defined by the custom project. Here's a simple example for the framework's configuration:

<bean id="iplIntegrationInfo" class="...IntegrationInfo">
<!-- myViewObjAccessor: to be defined in project specific Spring config file -->
<property name="viewObjAccessor" ref="myViewObjAccessor" />
<!-- myContextResolver: to be defined in project specific Spring config file -->
<property name="contextResolver" ref="myContextResolver" />
...
</bean>

<!-- These can be used for aliases if standard implementation should be used -->
<bean id="defaultViewObjAccessor" class="..." />
<bean id="defaultContextResolver" class="..." />

As you can see, all references are injected into the main configuration (iplIntegrationInfo). However, the referenced beans are not actually defined but have to be provided by the project. So, here's an example for the project's configuration:

<!-- use default -->
<alias alias="myViewObjAccessor" name="defaultViewObjAccessor" />

<!-- use custom implementation -->
<bean id="myContextResolver" class="..." />

Here we use the default for the first bean (by just establishing an alias for the configuration done in the framework file), and a custom implementation for the second.

This approach works, but obviously has a few drawbacks:

  • Configuration is shared between framework and project specific configuration code.
  • Project needs to know the framework's Spring file to do its work.
  • Internal framework structures (bean names, classes) are exposed to the outside.
  • A lot of XML code is required, even if using all the defaults.

Using Custom Namespaces

What should I say, we have switched to custom namespace lately and now configuration looks like this:

<ui:view-config/>

That's as short as it can be, but still is a complete configuration in case the project is using default implementations for all the beans. If the project would like to override some settings, the configuration file may be:

<ui:view-config>
<ui:viewobj-accessor ref="viewObjAccessor"/>
<ui:context-resolver ref="contextResolver"/>
</ui:view-config>

<bean id="viewObjAccessor" class="..." />
<bean id="contextResolver" class="..." />

Hence, you have the option to override all default implementations, and use meaningful tags to do so. Can you see the gains?

How Does This Magic Work?

I'm not going to provide full description on how to author custom namespaces since that is available in the Spring reference documentation and elsewhere. So, just a few basics to give you the idea...

First of all, you have to provide an XML schema describing your namespace. Then you have to implement a Namespace Handler that links each tag of your namespace to an XML parser, the Bean Definition Parser. And then, of course, those parsers must be implemented.

Each bean defintion parser is supposed to parse the XML element (including all attributes and sub elements) and to build the appropriate Spring beans. Spring provides a small hierarchy of classes you can use, depending on your situation:

  • The most specific is AbstractSimpleBeanDefinitionParser that fits well when there is a strong correlation between the attributes on a tag and the properties on your bean. In this case, there is really few code on your side.
  • The AbstractSingleBeanDefinitionParser is a bit more general, it allows you to create any single bean definition for an arbitrary complex nested XML structure. This involves more coding, of course, but still does some work for you (like automatically registering the bean in the context). This is the one you'll probably use most of the time.
  • The AbstractBeanDefinitionParser is even more general and allows you to create multiple bean definitions and register them directly. It takes care of id generation and a few other things.
  • Instead of using the latter one, you could also implement the BeanDefinitionParser interface directly, giving you all the flexibility you need.

All in all, you'll need a few hours to get comfortable with all the classes that are used to build up the bean definitions (DomUtils, BeanDefinition, BeanDefinitionBuilder, RuntimeBeanReference and ManagedMap/ManagedList to name a few).

But after that, building the parser and creating/registering your beans is quite straightforward. Moreover, you always can sneak a peek on how Spring itself is doing it for the Spring provided custom namespaces (like for Spring Security, for instance).

Okay, that's all for now, so go ahead and make life easier for your customers, your team, or yourself by providing a well-designed custom Spring namespace!

Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in Spring | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Maven Setting for Using a Single Repo Manager
    In a previous post I have tried to explain why it's a good idea to define your Maven repository in your settings.xml file instead of t...
  • Maven Plugins: Current Versions
    Upgrading Maven Plugins In preparation for a later switch to Maven 3 (which is already knocking on the door ) as well as to get rid of some ...
  • Maven Profiles: Activation... or not
    I love Maven. Really, I do. I should say that since this is my first post in my own blog (I know, I'm probably the last man on the plane...
  • Eclipse: User Operation is Waiting, and Waiting, ...
    I am using Eclipse since quite a long time, sometimes around 2002. That was version 2.0, if I remember correctly. Since then, I have always ...
  • Maven Documentation: The Missing List
    A rather weak talent of Maven is probably its documentation. This is my personal opinion, but it seem to match what other people think . Y...
  • DocBook with Maven Issue
    We are using DocBook for writing technical documentation for all our projects and in-house frameworks. We are actually quite happy with thi...
  • Maven Compromised by Plugins
    Every piece of software has its flaws... The important part is how the project is dealing with bugs. Maven is fine With Maven, the situation...
  • Maven Plugins: Upgrade with Care!
    Upgrading Maven Plugins: Tips and Issues After having shown the list of current Maven plugin versions in my previous post , now I'm goin...
  • Maven Plugin Releases: Do it yourself!
    In my previous post , I have complained about Maven plugins that do not release new versions although there are blocking issues that are rep...
  • Spring: Use Custom Namespaces!
    Have you ever heard of custom XML namespaces for Spring? I know you love Spring (like I do), so... probably yes. They are available since Sp...

Categories

  • BestPractices
  • Cargo
  • Checkstyle
  • Eclipse
  • Google
  • Hudson
  • Java
  • JBoss
  • JEE
  • Jenkins
  • JUnit
  • Maven
  • Nexus
  • oAW
  • Optimization
  • OSGi
  • Performance
  • Profiles
  • QA
  • Size
  • Spring
  • Testing
  • Tools
  • WebApp
  • Windows

Blog Archive

  • ►  2011 (5)
    • ►  May (1)
    • ►  April (1)
    • ►  March (2)
    • ►  February (1)
  • ►  2010 (11)
    • ►  October (2)
    • ►  September (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (4)
    • ►  January (2)
  • ▼  2009 (30)
    • ►  December (3)
    • ►  November (4)
    • ►  October (2)
    • ▼  September (3)
      • Spring: Use Custom Namespaces!
      • Spring: Test Framework Never Heard of Web Apps?
      • Highlight your Syntax
    • ►  June (4)
    • ►  May (5)
    • ►  April (4)
    • ►  March (5)
Powered by Blogger.

About Me

Unknown
View my complete profile