In my current app, I have done xml configurations on Spring Servlet and Hibernate; and it works as I want. However, look at the xml files, I don't really understand and it is quiet a challenging for future developing. Hence, I want to translate it to Java Configuration. But again, looks at my configuration xml files and follow the information of this guide make me so confused. So would anyone help me to bootstrap my application?
This is my root-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
servlet-contenxt.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
/*Omit some code here*/ >
<context:component-scan base-package="com.core.domain" />
<context:component-scan base-package="com.core.dao.generic" />
<context:component-scan base-package="com.core.dto" />
<context:component-scan base-package="com.web.page" />
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="sessionFactory" scope="singleton"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id ="transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
This is my hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/database</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hibernate.jdbc.batch_size">50</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">600</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">1800</property>
<property name="hbm2ddl.auto">update</property>
<!-- Resources mapping -->
<mapping class="com.common.domain.Account"/>
</session-factory>
</hibernate-configuration>
Right now, I only able to get rip of some config in web.xml with the following javaConfig bootstrap. The bootstrap still have to read the servlet-context.xml and I try to translate it to java code but unable to do so yet.
public class Bootstrap implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container)
throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfiguration.class);
container.addListener(new ContextLoaderListener(rootContext));
XmlWebApplicationContext servletContext = new XmlWebApplicationContext();
servletContext.setConfigLocation("classpath:servlet-context.xml");
ServletRegistration.Dynamic dispatcher = container.addServlet(
"SpringDispatcher", new DispatcherServlet(servletContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
and for Hibernate Persistence Config:
public class PersistenceConfig {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean sessionFactory() {
System.out.println("Create SessionFactory");
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(new String[] {
"com.common.domain.Account"
});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource restDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("org.postgresql.Driver"));
dataSource.setUrl(env.getProperty("jdbc:postgresql://localhost:5432/app"));
dataSource.setUsername(env.getProperty("username"));
dataSource.setPassword(env.getProperty("password"));
return dataSource;
}
/**
* Setting up the hibernate transaction Manager
* @param sessionFactory
* @return
*/
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.dialect", env.getProperty("org.hibernate.dialect.PostgreSQLDialect"));
setProperty("hibernate.globally_quoted_identifiers", "true");
}
};
}
}
There are many ways of creating config files in Spring, pure XML, pure Java, or a combination of both. Assuming you want to do everything in Java, you have to let go of the web.xml
and servlet-context.xml
files completely. Do note, however, that there are some entries in web.xml
that, AFAIK, cannot be converted into Java code.
First, you need an initializer. The Bootstrap
class you made that extends WebApplicationInitializer
is one way to do it.
Now, to convert the servlet-context.xml
into Java, you should have a class (doesn't matter what name) that would look something like this:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.core.domain", "com.core.dao.generic" /* OTHER PACKAGES CONTAINING @Controller */})
@Transactional
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver jspViewResolver() {
InternalResourceViewResolver jspViewResolver = new InternalResourceViewResolver();
jspViewResolver.setPrefix("/WEB-INF/views/");
jspViewResolver.setSuffix(".jsp");
return jspViewResolver;
}
@Bean
@Scope(value = "singleton") /* Actually, default is singleton */
public SessionFactory sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setConfigLocation("classpath:hibernate.cfg.xml");
return sessionFactory.getObject();
}
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
@Bean /* This should be present when using @Transactional (see annotations above) */
public TransactionManager tx() {
HibernateTransactionManager tx = new HibernateTransactionManager();
tx.setSessionFactory(this.sessionFactory());
return tx();
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
This would be the equivalent Java code of your servlet-context.xml. Make sure you pass this to the Initializer so that Beans can be initialized and used properly. This means you need to change the type of servletContext and pass in WebMvcConfig.class instead.
Hope this helps.