Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Sunday, December 11, 2016

Using Spring Framework’s Application Events and Listeners

Without any special configuration, Spring Framework automatically acts as a message broker in a pub/sub environment. To publish messages, you call the publishEvent method on an instance of org.springframework.context.ApplicationEventPublisher and pass it an instance of org.springframework.context.ApplicationEvent. You can obtain an ApplicationEventPublisher in a Spring-managed bean either through dependency injection or by implementing org.springframework.context.ApplicationEventPublisherAware. With an ApplicationEventPublisher instance, you can publish as many events as you want as often as you need to.
Subscribing to events is equally easy. Given an event FooEvent extends ApplicationEvent, a Spring bean needs only to implement org.springframework.context.ApplicationListener<FooEvent> to subscribe to FooEvent messages. To subscribe to BarEvent, implement ApplicationListener<BarEvent>. You can create and subscribe to a hierarchy of events, too. For example, consider the following event definitions:

public class TopEvent extends ApplicationEvent { }
public class MiddleEvent extends TopEvent { }
public class CenterEvent extends TopEvent { }
public class BottomEvent extends MiddleEvent { }

Given this, a bean that implements:

- ApplicationListener<ApplicationEvent> subscribes to all events
- ApplicationListener<TopEvent> subscribes to TopEvent, MiddleEvent, CenterEvent, and BottomEvent
- ApplicationListener<MiddleEvent> subscribes to MiddleEvent and BottomEvent
- ApplicationListener<CenterEvent> subscribes only to CenterEvent
- ApplicationListener<BottomEvent> subscribes only to BottomEvent

Wednesday, December 7, 2016

Configuring Validation in the Spring Framework Container

At its simplest, configuring Spring Framework’s LocalValidatorFactoryBean is as simple as instantiating it and returning it in a @Bean method in the RootContextConfiguration class:

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
     return new LocalValidatorFactoryBean();
}

The LocalValidatorFactoryBean automatically detects the Bean Validation implementation on the classpath, whether that’s Hibernate Validator or some other implementation, and uses its default javax.validation.ValidatorFactory as the backing factory. There’s no need to set up the META-INF/validation.xml file usually required to take advantage of Bean Validation in your application. However, sometimes there is more than one Bean Validation Provider on the classpath (for example, when running within a full Java EE application server such as GlassFish or WebSphere).
In these cases, which provider Spring selects is unpredictable (it might even change each time!), so you should set the provider class manually if you prefer the provider to be predictable.

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
     LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
     validator.setProviderClass(HibernateValidator.class);
     return validator;
}

The only downside to doing this is that it requires Hibernate Validator to be a compile-time dependency instead of a runtime dependency. This pollutes your compile time classpath, meaning your IDE will sometimes make code suggestions that you don’t want. You can avoid this by loading the class dynamically, which of course has its own downside in that any mistakes in the name will not be caught at compile time.

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
          throws ClassNotFoundException
{
     LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
     validator.setProviderClass(Class.forName(
          "org.hibernate.validator.HibernateValidator"
     ));
     return validator;
}

N.B. Setting the provider class manually is not necessary when using Tomcat.