Spring the Code over XML!

Everybody knows when Spring started, it was all XMLs, which helped to define the dependencies and wirings. But with the introduction of @Configuration, things got a lot easier, and we could get rid of those long, never ending confusing XMLs. Having your configuration as Java code is always better than in XMLs.

spring

Why and how does that help?

Type-Safe – Compilation will fail if there are errors in the code. There could be a lot of typing errors while writing a XML, and we wouldn’t know it even after compilation. If failing, then fail early.
Short and Modular – XMLs tend to get very huge, and identifying the modules often gets cumbersome. Java code can be modularised into methods, and is easily readable.
IDE Support – We have autocompletion/refactoring support available from a lot of IDE’s, and is easier to see the available options for code.
Maintainable – Java code is always better maintainable and manageable than the XMLs
Multiple Profile Support – Support for multiple profiles with @Profile annotation(Spring Documentation)

How did we do it?

We got a chance to migrate configuration written in XML to Java Code Configuration .It was easy to do it since Spring had almost the same names for the classes as that of the XML elements. Listing the changes we did for the conversion:

We had two contexts defined for the application – Application level context and a Servlet level context.
The ApplicationContext was defined as:
@Configuration
@EnableTransactionManagement
public class ApplicationContext {
and the ServletContext as:
@Configuration
@ComponentScan(“com.example.shriram")
@EnableWebMvc
public class ServletContext extends WebMvcConfigurerAdapter {
If you see here, the component scanning was converted from
<context:component-scan base-package=<span style="font-family: 'Trebuchet MS';">“com.example.shriram"</span> />
to @Component annotation
@ComponentScan(“com.example.shriram")
Now coming to each individual beans,
Property Placeholder
<context:property-placeholder location="classpath:env.properties" />
was converted to
@Bean(name = "envProperties")
public PropertiesFactoryBean envPropertiesMapper() {
  PropertiesFactoryBean bean = new PropertiesFactoryBean();
  bean.setLocation(new ClassPathResource("env.properties"));
  return bean;
}
PropertiesFactoryBean – Allows for making a properties file from a classpath location available as Properties instance in a bean factory. Can be used to populate any bean property of type Properties via a bean reference.(Spring Documentation)

DataSource JNDI Configuration
DataSource – We had a JNDI configured, and JndiDataSourceLookup(Spring Documentation) helped us to do a datasource lookup
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <description>Datasource name- Use datasource name in the "jndiName"property
  </description>
  <property name="jndiName" value="${jndiname}" />
</bean>
to
@Bean
public DataSource dataSource() {
  JndiDataSourceLookup dataSource = new JndiDataSourceLookup();
  dataSource.setResourceRef(true);
  return dataSource.getDataSource(jndiName);
}
InternalResourceViewResolver – This was changed from:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix">
    <value>/WEB-INF/</value>
  </property>
  <property name="suffix">
    <value>.jsp</value>
  </property>
</bean>

to

@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
  InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
  viewResolver.setPrefix("/WEB-INF/");
  viewResolver.setSuffix(".jsp");
  return viewResolver;
}
CustomJacksonObjectMapper – This was tricky – We had a custom Jackson mapper to convert our response object as JSON. So, we had to add our CustomerJacksonMapper to the JSONConvertor which in turn was added to the list of HTTPMessageConverters.
<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class=“org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
      <property name="objectMapper">
       <bean class=“com.example.shriram.util.CustomJacksonObjectMapper" />
      </property>
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>
to
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(converter());

}

@Bean
MappingJackson2HttpMessageConverter converter() {
  MappingJackson2HttpMessageConverter jsonConverter = new   MappingJackson2HttpMessageConverter();
  ObjectMapper objectMapper = new ObjectMapper();
  objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
  jsonConverter.setObjectMapper(objectMapper);
  return jsonConverter;
}
Interceptors – We also added an authentication interceptor to authenticate every API Call. An instance of the AuthenticationInterceptor was created and added to the registry of Interceptors.
@Bean
public AuthenticationInterceptor authenticationInterceptor() {
   return new AuthenticationInterceptor();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
   registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");

}
This is how we migrated XMLs to Java Code. As you can see, Spring @Configuration classes can be very powerful in defining application or servlet context. This gives us the flexibility to have multiple configuration classes and makes the code more cleaner, maintainable and robust.
This post might be out of it’s time, but I got to learn something new and better.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s