All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.
The following topics are discussed:
1. Goals of Spring JavaConfig;
2. Spring Librairies Update
3. Overview of Spring JavaConfig;
4. Sample of AppConfig.java;
5. Sample of a Spring business service.
6. Sample of MvcConfig.java;
7. Sample of a Spring controller.
8. Considerations
(view of Spring app in action)
1. Goals of Spring JavaConfig
The main goal of Spring JavaConfig is to eliminate the XML code used to configure all the Spring components and to keep all the configuration in 2 main JavaConfig classes, namely, for example, AppConfig.java and MvcConfig.java.
This means practically passing all the configuration from XML to Java classes.
Note: this post is based on the previous one, namely "Spring 3.0 Java Configuration" which you should read before this one; next, we'll try to show that almost all the JavaConfig problems found at Spring 3.0 were solved at Spring Framework 3.1 release.
2. Spring Librairies Update
If you followed the Genereal Considerations, at the section "4. Assembly librairies" we used some Spring Framework 3.0.5 libraries. Now, these libs should be replaced with Spring Framework 3.1.0 libs.
So, in your app classpath, replace these libs:
<<
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-javaconfig-1.0.0.m3.jar
spring-jdbc-3.0.5.RELEASE.jar
spring-orm-3.0.5.RELEASE.jar
spring-tx-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
>>
, with these ones:
<<
org.springframework.asm-3.1.0.RELEASE.jar
org.springframework.beans-3.1.0.RELEASE.jar
org.springframework.context-3.1.0.RELEASE
org.springframework.core-3.1.0.RELEASE.jar
org.springframework.expression-3.1.0.RELE
org.springframework.jdbc-3.1.0.RELEASE.jar
org.springframework.orm-3.1.0.RELEASE.jar
org.springframework.transaction-3.1.0.RELEASE.jar
org.springframework.web-3.1.0.RELEASE.jar
org.springframework.web.servlet-3.1.0.RELEASE.jar
>>
3. Overview of Spring JavaConfig
As we said before at Spring 3.0 JavaConfig, there are used special annotations in JavaConfig: @Configuration, @Import, @ImportResource, @Bean, aso.
For the Spring 3.1 JavaConfig, we'll use another annotations: @ComponentScan and @EnableTransactionManagement.
The @ComponentScan annotation intends to solve the problems of scanning packages for Spring components, in order for us not to define them in AppConfig.java and MvcConfig.java.
The @EnableTransactionManagement annotation will tell Spring to use driven annotated transactions or, more exactly, to detect the @Transactional annotation that we mapped in a Spring business component; The @EnableTransactionManagement annotation is equivalent to XML tag declaration: <tx:annotation-driven />, so after we use @EnableTransactionManagement we'll not need anymore the app-config.xml file that was imported in AppConfig.java (see Spring 3.0 JavaConfig).
4. Sample of AppConfig.java;
<<
package blog.configuration;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@ComponentScan("blog.services")
@EnableTransactionManagement
public class AppConfig {
@Bean(name="dataSource")
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("");
ds.setUrl("jdbc:mysql://127.0.0.1:3306/blog");
return ds;
}
@Bean(name="sessionFactory")
public SessionFactory sessionFactory() {
AnnotationSessionFactoryBean factoryBean = null;
try {
factoryBean = new AnnotationSessionFactoryBean();
Properties pp = new Properties();
pp.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
pp.setProperty("hibernate.max_fetch_depth", "3");
pp.setProperty("hibernate.show_sql", "false");
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan(new String[] {"blog.dao.*"});
factoryBean.setHibernateProperties(pp);
factoryBean.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return factoryBean.getObject();
}
@Bean(name="transactionManager")
public HibernateTransactionManager transactionManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
>>
Note: we observe in this file all the Java bean objects (Spring business components) that we defined in AppConfig.java at Spring 3.0 JavaConfig dissapeared. Also notice the presence of @ComponentScan and @EnableTransactionManagement annotations.
5. Sample of a Spring business service.
We will pass here the Java code used to create the Zone Spring service (namely ZoneDaoImpl), as an implementation of a user created ineterface (namely ZoneDao):
<<
package blog.services;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import blog.dao.ZoneDao;
import blog.dao.entities.Zone;
@Service
public class ZoneDaoImpl implements ZoneDao {
private SessionFactory sessionFactory;
@Autowired
public ZoneDaoImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Zone> getZones() {
return (List<Zone>) getCurrentSession().createQuery("from Zone").list();
}
@Transactional(readOnly = true)
public Zone getZoneByCod(String cod) {
return (Zone) getCurrentSession().createQuery("from Zone z where z.cod=?").setParameter(0, (String) cod).uniqueResult();
}
@Transactional(readOnly = true)
public Zone getZoneByName(String name) {
return (Zone) getCurrentSession().createQuery("from Zone z where z.name=?").setParameter(0, (String) name).uniqueResult();
}
protected Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
>>
Note: as we used @ComponentScan in AppConfig.java, we need to use the @Service and @Autowired in ZoneDao Spring service.
6. Sample of MvcConfig.java;
<<
package blog.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan("blog.controllers")
public class MvcConfig {
@Bean
InternalResourceViewResolver irResolver() {
InternalResourceViewResolver ir = new InternalResourceViewResolver();
ir.setPrefix("/views/");
ir.setSuffix(".jsp");
return ir;
}
}
>>
Note: we observe in this file all the Java bean objects (Spring controllers) that we defined in MvcConfig.java at Spring 3.0 JavaConfig dissapeared. Also notice the presence of @ComponentScan.
Note: Because we replaced OpenSessionInViewInterceptor with OpenSessionInViewFilter and moved it in web.xml, we do not need anymore the mvc-config.xml file.
7. Sample of a Spring controller.
We will pass here the code used to create the Zone controller (namely ZoneController):
<<
package blog.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import blog.dao.ZoneDao;
@Controller
public class ZoneController {
private ZoneDao zoneDao;
@Autowired
public ZoneController(ZoneDao zoneDao) {
this.zoneDao = zoneDao;
}
@RequestMapping("/zoneList")
public String zoneList(Model model) {
model.addAttribute("zones", zoneDao.getZones());
return "zoneList";
}
}
>>
Note: as we used @ComponentScan in MvcConfig.java, we need to use the @Controller and @Autowired in ZoneController.
8. Considerations
The Spring JavaConfig may be useful as:
- we may keep all the configuration in 2 Java classes;
- no XML code for XML haters;
However, when used Spring 3.1 JavaConfig, I still haven't found a way to map the OpenSessionInViewInterceptor at the level of MvcConfig.java; a starting point could be to inherit the WebMvcConfigurerAdapter class in MvcConfig.java and to override the addInterceptors() method