How to use applicationContext.xml in springboot and how to override bean values

1. Introduction

This post would demo how to setup beans with applicaitonContext.xml and how to override bean properties in the spring or springboot applications.

2. Environments

  • SpringBoot 1.x+
  • Java 1.8+

3. The Pom.xml

spring boot version:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.12.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

all dependencies:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

4. The database and table

For demo purpose, I setup one database in localhost as follows:

CREATE DATABASE `test` CHARACTER SET utf8 COLLATE utf8_bin;

There is a table ‘tbl_student’ in both of the databases:

CREATE TABLE `tbl_student` (
  `ID` int(10) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(100) NOT NULL,
  `BRANCH` varchar(255) NOT NULL,
  `PERCENTAGE` int(3) NOT NULL,
  `PHONE` int(10) NOT NULL,
  `EMAIL` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

And insert one record into that table:

INSERT INTO `tbl_student` (`ID`, `NAME`, `BRANCH`, `PERCENTAGE`, `PHONE`, `EMAIL`)
VALUES
    (1, 'jack', 'it', 20, 1211232, '[email protected]');

5. The domain class Student

public class Student {
    private int id;
    private String name;
    private String branch;
    private int percentage;
    private int phone;
    private String email;

    //getters and setters
    ...
}

6. The applicationContext.xml and properites file

We can define a file named applicationContext.xml in src/main/resources/, here is the content:

src/main/resources/applicationContext.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">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>

    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

Then we need a properties file named jdbc.properties in src/main/resources too.

src/main/resources/jdbc.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=yes&amp;characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

7. Import the applicationContext.xml into springboot application

Now we can use the annotation @ImportResource to import applicationContext.xml into our springboot application.

src/main/sba/MyApp.java

package sba;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

import javax.sql.DataSource;

@SpringBootApplication
@ImportResource({"classpath*:applicationContext.xml"})
public class MyApp {
    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(MyApp.class, args);
    }
}

What is @ImportResource?

@Retention(value=RUNTIME)
 @Target(value=TYPE)
 @Documented
public @interface ImportResource

Indicates one or more resources containing bean definitions to import.

Like @Import, this annotation provides functionality similar to the <import/> element in Spring XML. It is typically used when designing @Configuration classes to be bootstrapped by an AnnotationConfigApplicationContext, but where some XML functionality such as namespaces is still necessary.

8. The DAO class

Then we define a Dao class to access the database.

src/main/sba/dao/StudentDao.java:

package sba.dao;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import sba.domain.Student;

import java.sql.ResultSet;
import java.sql.SQLException;


@Component
public class StudentDao {
    @Autowired
    private JdbcTemplate jdbcTemplateObject;

    public Student getStudent(Integer id) {
        String SQL = "select * from tbl_student where id = ?";
        Student student = jdbcTemplateObject.queryForObject(SQL,
                new Object[]{id}, new StudentMapper());

        return student;
    }

    class StudentMapper implements RowMapper<Student> {
        @Override
        public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
            Student student = new Student();
            student.setId(rs.getInt("id"));
            student.setName(rs.getString("name"));

            return student;
        }
    }
}

9. The JUnit testcase

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestDefaultDataSource {
    @Autowired
    private StudentDao studentDao;
    @Test
    public void testSimpleSelect() {
        Student student = studentDao.getStudent(1);
        assertNotNull(student);
        assertEquals(student.getName(),"jack");
    }
}

Run the testcase, we got a green bar. junit_greenbar

10. How to override the property values in jdbc.properties?

You can see that we have used the PropertyPlaceholderConfigurer to configure our application properties in applicationContext.xml, if you want to override the property values in jdbc.properties , you can do as follows:

Step #1: Add property file to the configurer list, change your applicationContext.xml as follows:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:jdbcOverridden.properties</value>
            </list>
        </property>
    </bean>

Step #2: Add src/main/resources/jdbcOverridden.properties file:

jdbc.password=1234QWER

Then we change our database’s root password to 1234QWER as follows:

ALTER USER 'root'@'localhost' IDENTIFIED BY '1234QWER'

Rerun the junit test, we get green bar too.

junit_greenbar

It’s so easy, do you think so?

The example code has been uploaded to github, you can visit here to view the example codes.