Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, January 29, 2010

ID design

We often take the IDs that we use in databases and applications for granted. As long as we can identify a data record with a unique number, everything is great. Recently, I ran into an interesting problem in an existing application. The ID that was used has this format:
ABBBCCC

A = last digit of year
BBB = day number of the year
CCC = sequence number
For example, you could get on 2 february 2009 this ID: 9033012. This would be the twelveth data record of the day.

More digits

Sometimes, the application would generate more than 1000 data records on a day and run out of numbers. In that case the application just add digits to get something like this:
ABBBCCCDDD

A = last digit of year
BBB = day number of the year
CCCDDD = sequence number with additional digits
Example: 9003123456

Perhaps you can sense some trouble here...

Monday, November 19, 2007

Spring bean configuration validation

If you enthousiastically use Spring like me and dutifully inject every dependency in your beans with Spring's XML configuration, you have probably encountered the situation that you forgot to inject a property and received a NullPointerException from an unexpected place in your code. Wouldn't it be nice to check the configuration of your bean after it is instantiated? Your bean could implement the InitializingBean interface, which would cause the Spring application context to call the afterPropertiesSet method after your bean is instantiated and injected with dependencies. This would make your bean directly dependent on Spring and you probably would not want that.

Attribute "init-method"

A better solution is to call a method of your bean that validates its own configuration with the "init-method" attribute of the bean element in the application context XML:
<bean id="bean1" class="net.kazed.spring.config.validator.ExampleBean1" init-method="validateConfiguration">
 <property name="bean2" ref="bean2"/>
 <property name="bean3" ref="bean3"/>
</bean>
public void validateConfiguration() {
 DependencyAssert.notNull(bean2, "bean2");
 DependencyAssert.notNull(bean3, "bean3");
}
The Spring container will call the "validateConfiguration" method after your bean, in which you can check if all required dependencies are injected. The only thing is that you should not forget to add the "init-method" attribute.

BeanPostProcessor

Since our goal was to catch configuration mistakes, this solution just is not good enough. Fortunately, you can create a post-processor for the Spring container that will examine every created bean after instantiation and dependency injection. By implementing a BeanPostProcessor, you can invoke the validateConfiguration method. To make it nice and intuitive, we can create an interface ValidatableConfiguration with the validateConfiguration method. Interface:
public interface ValidatableConfiguration {
/**
 * Validate the configuration of the object.
 */
void validateConfiguration();
}
ValidatingBeanProcessor:
public class ValidatingBeanProcessor implements BeanPostProcessor {
  public Object postProcessBeforeInitialization(Object bean, String beanName)
   throws BeansException {
   return bean;
  }

  public Object postProcessAfterInitialization(Object bean, String beanName)
   throws BeansException {
   if (bean instanceof ValidatableConfiguration) {
     try {
       ((ValidatableConfiguration) bean).validateConfiguration();
     } catch (DependencyNullException e) {
       throw new ConfigurationValidationException("Configuration of bean '" + beanName
         + "' failed - " + e.getMessage(), e);
     }
   }
   return bean;
  }
}
We just declare the ValidatingBeanProcessor once in the application context, and the container will use it for every created bean:
<bean id="beanValidator" class="net.kazed.spring.config.validator.ValidatingBeanProcessor">
The nice thing is that we only have to make the bean implement the ValidatableConfiguration interface and it will automatically be used to validate the bean whenever you declare it in the application context. Advantages:
  • Intuitive design - implement interface and it will be validated
  • No special configuration (except from the one ValidatingBeanProcessor)
  • Validation is done only once and during instantiation of the application context - it will fail early
  • Error message is descriptive - no more puzzling NullPointerException

Constructor injection

Traditionally, the Spring team favored setter injection because of more readable configuration. Spring has always also supported constructor injection and recently this has received more attention in the Spring community (see Alef's blog). Constructor injection makes validation incredibly simple: just validate in the constructor.
public ExampleBean1(ExampleBean2 bean2, ExampleBean3 bean3) {
 super();
 DependencyAssert.notNull(bean2, "bean2");
 DependencyAssert.notNull(bean3, "bean3");
 this.bean2 = bean2;
 this.bean3 = bean3;
}
<bean id="bean1c" class="net.kazed.spring.config.validator.ExampleBean1">
 <constructor-arg ref="bean2"/>
 <constructor-arg ref="bean3"/>
</bean>
As you can see, constructor injection is a bit harder to read because the arguments are nameless and depend on the order.

Conclusion

I would prefer to use constructor injection and use (or combine with) setter injection if some dependencies are optional. The BeanPostProcessor is very useful because it is non-obtrusive and automatically validates the configuration of a bean when it implements an interface that you define yourself and can be a logical part of your domain model. Retrieve here the source code of these examples.

Friday, October 26, 2007

Create your own JSF variable resolver

The system I am working on, uses a singleton service factory (that uses Spring to configure the services) to lookup service instances. The JSF backing beans use these services to perform business operations and need to lookup the services with the central service locator. This is quite straightforward and unfortunately less straightforward when you want to unit test it: it would be a lot easier to inject the services into the backing beans like we are used to in Spring. Spring has a variable resolver that makes it possible to inject Spring managed beans defined in WEB-INF/applicationContext.xml into JSF managed beans. For various reasons the system I am working on cannot put the services in application context of the web application (service instances must be shared between multiple web applications on the server). To make the same sort of injection possible, I created a JSF variable resolver that will lookup the desired service in the global service locator.
public class ServiceLocatorVariableResolver extends VariableResolver {

private VariableResolver originalVariableResolver;
private ServiceLocator serviceLocator;

/**
* Constructor.
* @param originalVariableResolver Original JSF variable resolver.
*/
public ServiceLocatorVariableResolver(VariableResolver originalVariableResolver) {
   this.originalVariableResolver = originalVariableResolver;
}

/**
* {@inheritDoc}
*/
public Object resolveVariable(FacesContext context, String name) throws EvaluationException {
   Object result = null;
   result = originalVariableResolver.resolveVariable(context, name);
   if (result == null) {
     if (serviceLocator == null) {
         serviceLocator = ServiceLocatorFactory.getInstance().getLocator();
     }
     try {
         result = serviceLocator.getBean(name);
     } catch (NoSuchBeanDefinitionException e) {
         // ignore exception - bean not found
     }
   }
   return result;
}
}
As you can see, creating a variable resolver is quite straightforward and make dependency injection possible, even if you use an old fashioned service locator. Unit testing becomes a lot easier this way.