Spring: Make your java-based configuration more elegant

Hi everyone, I haven’t written new articles a long period of time. A lot of materials were accumulated which need to be posted in my blog in nearest future. But now I want to talk about Spring MVC application configurations. If to be more precisely, I want to talk about java based Spring configurations.

Despite that Spring java based configuration was introduced in 3.0 version, many developers still use XML-based approach. Personally I use annotation based configurations, because they are more convenient in management, in development and in maintenance. If you have read my blog before you could noticed that in all code examples I used exactly java based configurations.

Not so long time ago I have made a code review of one my project. I noticed that something is wrong with a structure of the configurations. Two aspects were bad as for me:

  • All beans were configured in a single class
  • Initialization on web app context was too complex

You can witness these two drawbacks in all my examples of Spring MVC applications. For example you can open one of my last tutorials about Spring REST services with CNVR. Take a look there on two classes: WebAppConfig and Initializer.


The first one represents the first point in this article. Definitely I need to do something to split beans configuration logically. To resolve this issue I decided to make two steps:

1) Move DB configurations in a separate class

public class DataBaseConfig {
    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
        private Environment env;
        public DataSource dataSource() {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();
                return dataSource;
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
                LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
                return entityManagerFactoryBean;
        private Properties hibProperties() {
                Properties properties = new Properties();
                properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
                properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
                return properties;        
        public JpaTransactionManager transactionManager() {
                JpaTransactionManager transactionManager = new JpaTransactionManager();
                return transactionManager;


2) Convert WebAppConfig class in a main configuration class and assign to it the rest of configuration (in current case it would be just DataBaseConfig class) classes via @Import annotation.

public class WebAppConfig extends WebMvcConfigurerAdapter {
        private Environment env;
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
                        .mediaType("html", MediaType.TEXT_HTML)
                        .mediaType("json", MediaType.APPLICATION_JSON)
        public ViewResolver contentNegotiatingViewResolver(
                        ContentNegotiationManager manager) {
                List< ViewResolver > resolvers = new ArrayList< ViewResolver >();
                InternalResourceViewResolver r1 = new InternalResourceViewResolver();
                JsonViewResolver r2 = new JsonViewResolver();
                ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
         return resolver;
        * View resolver for returning JSON in a view-based system. Always returns a
        * {@link MappingJacksonJsonView}.
        public class JsonViewResolver implements ViewResolver {
                public View resolveViewName(String viewName, Locale locale)
                                throws Exception {
                                MappingJacksonJsonView view = new MappingJacksonJsonView();
                                return view;


In this way you can separate single big configuration class in several smaller which will contain specific configs for them.


Code of Initializer class is too verbose in the example which I mentioned above and provided the link to it. I registered there the web application root configurations, mapping and filter. How I can decrease a number of code lines? The answer I got looking on AbstractAnnotationConfigDispatcherServletInitializer class. Look on the class and you will notice that it implements WebApplicationInitializer interface, which I have implmented in my previous version of the Initializer class. So here is a new version of the Initializer:

public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {

        protected Class< ? >[] getRootConfigClasses() {
                return null;

        protected Class< ? >[] getServletConfigClasses() {
                return new Class< ? >[] { WebAppConfig.class };

        protected String[] getServletMappings() {
                return new String[] { "/" };

        protected Filter[] getServletFilters() {
                return new Filter[] { new HiddenHttpMethodFilter() };


Thank to these two steps I have made my configurations for Spring MVC application more elegant. Now you can do it too. Good luck

  • Ajesh Baby

    Your DatabaseConfig file is very interesting. From this inspiration I would like to change my Spring with JSF integration project to Java Config. My project uses Atomikos Transaction Manager and Apache DBCP Data Source for pooling.


    public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {


    protected Class[] getRootConfigClasses() {

    return null;



    protected Class[] getServletConfigClasses() {

    return new Class[] { WebAppConfig.class };



    protected String[] getServletMappings() {

    return new String[] { “/”, “/*”, “*.faces”, “*.xhtml” };



    public void onStartup(ServletContext servletContext)

    throws ServletException {

    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();

    //scan the package of your @Configuration java files


    servletContext.addListener(new ContextLoaderListener(root));

    servletContext.addServlet(“Faces Servlet”, “javax.faces.webapp.FacesServlet”);

    servletContext.setInitParameter(“javax.faces.STATE_SAVING_METHOD”, “server”);

    servletContext.setInitParameter(“com.sun.faces.expressionFactory”, “com.sun.el.ExpressionFactoryImpl”);

    servletContext.setInitParameter(“primefaces.PRIVATE_CAPTCHA_KEY”, “6LfwZwoAAAAAAEhRyntKF1PBzysAJLzqp2v-GMRR”);

    servletContext.setInitParameter(“primefaces.PUBLIC_CAPTCHA_KEY”, “6LfwZwoAAAAAAI-oUHpdvRnkMfu9fXQHxc0P7IBu”);

    servletContext.setInitParameter(“javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE”, “true”);

    servletContext.setInitParameter(“primefaces.THEME”, “redmond”);

    servletContext.setInitParameter(“primefaces.SUBMIT”, “partial”);




    protected Filter[] getServletFilters() {

    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();


    OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter();


    return new Filter[] { characterEncodingFilter, openEntityManagerInViewFilter, new org.primefaces.webapp.filter.FileUploadFilter()};






    public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();




    return viewResolver;






    @ComponentScan(basePackages= “com.shiv.ShivCDB.dao”)

    @PropertySource(value = “classpath:ShivCDB-dao.properties”)

    public class DatabaseConfig {


    private String driverClassName;


    private String url;


    private String username;


    private String password;


    private int maxIdle;


    private int maxActive;


    private String dialect;


    private boolean showSql;


    private boolean generateDdl;


    public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {

    PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();

    ppc.setLocation(new ClassPathResource(“ShivCDB-dao.properties”));


    return ppc;



    public javax.sql.DataSource dataSource() {

    org.apache.commons.dbcp.BasicDataSource mysqlDs = new org.apache.commons.dbcp.BasicDataSource();

    try {








    } catch (java.sql.SQLException e) {

    // TODO Auto-generated catch block



    return mysqlDs;



    public LocalContainerEntityManagerFactoryBean sessionFactory() {

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();




    org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter jpaVendorAdapter = new org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter();





    factoryBean.setJpaPropertyMap( new java.util.HashMap() {{

    put(“hibernate.transaction.factory_class”, “org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory”);

    put(“hibernate.transaction.manager_lookup_class”, “com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup”);

    put(“hibernate.connection.release_mode”, “on_close”);


    return factoryBean;




    public JtaTransactionManager jtaTransactionManager() throws javax.transaction.SystemException {

    JtaTransactionManager transactionManager = new JtaTransactionManager();

    com.atomikos.icatch.jta.UserTransactionManager atomikosTransactionManager = new com.atomikos.icatch.jta.UserTransactionManager();






    com.atomikos.icatch.jta.UserTransactionImp atomikosUserTransaction = new com.atomikos.icatch.jta.UserTransactionImp();




    return transactionManager;



    I can’t get more information from web, so I create my own effort. But I can’t connect jtaTransactionManager() with sessionFactory() for provide JTA @Transaction.

    Below mentioned my working xml config code part. Please help me to go with Java Config.

  • Radha

    Hi your examples are succinct. I have a requirement of loading properties files from WEB-INF/properties folder. @PropertySource loads the files from class path. Can you suggest me with any approach?

    • http://fruzenshtein.com/ Alex Zvolinskiy

      Try something like this:


      • Radha

        Hi Alex,

        i am glad to have your answer. My folder structure is something like this

        —- resources


        You mean- propertiySourcesPlaceholderConfigurer(ClassName.class.getClassLoader().getResourceAsStream(properties/settings/*.properties) in the PropertiySourcesPlaceholderConfigurer bean configuration right?

        What is the ClassName to provide?

        Whether i have to include /WEB-INF in the getResourcAsStream() or not?

  • Radha

    Hi Alex Zvolinskiy,

    i have followed this notes to create and destroy the http session. It is getting created and destroyed but, it is not redirected to specified url in spring security configuration as shown below,


    My log is here

    ==== Session is destroyed ====

    ==== Session is destroyed ====

    ==== Session is destroyed ====

    DEBUG – Checking match of request : ‘/xxx/xxx/xxx.view’; against ‘/resources/**’

    DEBUG – /xxx/xxx/xxxx.view?_=1403521901218&_ajaxcall=true&screenId=9 at position 1 of 12 in additional filter chain; firing Filter: ‘WebAsyncManagerIntegrationFilter’

    DEBUG – /xxx/xxx/xxxx.view?_=1403521901218&_ajaxcall=true&screenId=9 at position 2 of 12 in additional filter chain; firing Filter: ‘SecurityContextPersistenceFilter’

    DEBUG – No HttpSession currently exists

    DEBUG – No SecurityContext was available from the HttpSession: null. A new one will be created.

    It is simply creating new session and proceeding further.
    Can you explain me the reason and way to solve this problem?

  • Yestay Muratov

    Hello, Like your post! I dont like xml configuration either. Can you please advise me some books in which I can learn how to program using annotations instead of xml?

    • http://fruzenshtein.com/ Alex Zvolinskiy

      Unfortunately I don’t know such books. Try to find something about Spring BOOT not later than 2014
      Or simply read an official docs and tutorials

    • Irdi Avxhi

      Spring in action learns u how to configure application context with java classes and xml for each example it gives both solutions. One of best books read about spring.