How To Read External Properties File In Spring Using PropertyPlaceholderConfigurer

If you want to save configuration data in an external properties file, and then read them in the spring application, you can use PropertyPlaceholderConfigurer class. This class has a location attribute where you can specify the external properties file location. It then can read the data from the external properties file, and you can use the data in that properties file with ${} operator in either XML configuration file or java source file. This can avoid parameter values hardcoded in spring source code and make your application more flexible.

This example will show you how to use PropertyPlaceholderConfigurer class ( by spring XML configuration) and PropertySourcesPlaceholderConfigurer class ( by spring java annotation ) in the spring application to read MySQL JDBC connection properties saved in the file jdbc.properties.

It will use both XML configuration and java annotation configuration to implement the goal. In this example, it will use the MySQL JDBC properties to build a commons dbcp Datasource object then use this Datasource object to implement insert, update, delete and select actions in the MySQL database table.

1. Spring Read External Properties File Use Xml Configuration.

  1. Define the PropertyPlaceholderConfigurer bean in the spring bean configuration XML file.
  2. Set the jdbc.properties file location to above bean’s locations attributes value.
  3. Then you can use ${property_key_name} to get related property values in the spring bean configuration XML file.

1.1 Create Example Project.

  1. Create an XML-based spring project. You can refer Xml Based Spring Configuration Example.
  2. Then add java source files, jdbc.properties file and pom.xml file as below.
    C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\SPRINGBOOT\READEXTERNALPROPERTIESXML
    │   pom.xml
    │
    ├───src
    │   └───main
    │       ├───java
    │       │   └───com
    │       │       └───dev2qa
    │       │           │   TestUserAccountDAO.java
    │       │           │
    │       │           ├───dao
    │       │           │       UserAccountDAO.java
    │       │           │
    │       │           └───dto
    │       │                   UserAccountDTO.java
    │       │
    │       └───resources
    │               ApplicationContextBeans.xml
    │               jdbc.properties

1.2 TestUserAccountDAO Java File.

  1. This class is used to test UserAccountDAO class methods.
  2. TestUserAccountDAO.java
    package com.dev2qa;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.dev2qa.dao.UserAccountDAO;
    import com.dev2qa.dto.UserAccountDTO;
    
    public class TestUserAccountDAO {
    
        public static void main(String[] args) {
    
            // Get spring beans context object.
            AbstractApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContextBeans.xml");
    
            // Get Spring UserAccountDAO bean.
            UserAccountDAO userAccountDao = (UserAccountDAO)context.getBean("userAccountDao");
    
            // Create a UserAccountDTO object.
            UserAccountDTO dto = new UserAccountDTO();
    
            System.out.println("================= Add first user Jerry ==================");
            // Add the first user account dto.
            dto.setUserName("Jerry");
            dto.setPassword("999999");
            dto.setEmail("[email protected]");
            userAccountDao.addUserAccount(dto);
            // Show the first user data.
            userAccountDao.selectUserAccount();
    
            System.out.println("================= Update Jerry password and email ==================");
            // Update above user account data.
            dto.setPassword("888888");
            dto.setEmail("[email protected]");
            userAccountDao.updateUserAccount(dto);
            // Show the updated result.
            userAccountDao.selectUserAccount();
    
            System.out.println("================= Add second user Richard ==================");
    
            // Add the second user account dto.
            dto.setUserName("Richard");
            dto.setPassword("111111");
            dto.setEmail("[email protected]");
            userAccountDao.addUserAccount(dto);
            // Show the second user data.
            userAccountDao.selectUserAccount();
    
            System.out.println("================ Delete user Richard ===================");
    
            // Delete the second user data.
            userAccountDao.deleteUserAccount("Richard");
            userAccountDao.selectUserAccount();
    
        }
    
    }

1.3 UserAccountDAO Java File.

  1. This class injects a DataSource object and uses it to get MySQL database server connection and implements database table insert, update, delete and select SQL command.
  2. UserAccountDAO.java
    package com.dev2qa.dao;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.sql.DataSource;
    
    import com.dev2qa.dto.UserAccountDTO;
    
    public class UserAccountDAO {
    
        private DataSource ds;
    
        private Connection connection = null;
    
        // Input DataSource object in the DAO constructure.
        public UserAccountDAO(DataSource dataSource) {
            this.ds = dataSource;
        }
    
        // Get the database connection object.
        private Connection getDatabaseConnection()
        {
            if(connection == null)
            {
                try {
                    connection = this.ds.getConnection();
                    // Manually commit database submit.
                    connection.setAutoCommit(false);
    
                } catch (SQLException ex) {
                    this.printSqlException(ex);
                }
            }
    
            return connection;
        }
    
        // Add user account method.
        public void addUserAccount(UserAccountDTO userAccountDto){
    
            Statement stmt;
            try {
                stmt = getDatabaseConnection().createStatement();
    
                StringBuffer strBuf = new StringBuffer();
    
                strBuf.append("insert into user_account(user_name, password, email) values ('");
    
                strBuf.append(userAccountDto.getUserName());
                strBuf.append("','");
                strBuf.append(userAccountDto.getPassword());
                strBuf.append("','");
                strBuf.append(userAccountDto.getEmail());
                strBuf.append("')");
    
                System.out.println(strBuf.toString());
    
                // Execute the insert sql command and register to return auto generated table row id.
                stmt.executeUpdate(strBuf.toString(), Statement.RETURN_GENERATED_KEYS);
    
                connection.commit();
    
                // Get generated id value in ResultSet.
                ResultSet rs = stmt.getGeneratedKeys();
    
                // First move result cursor to the first row, otherwise it will throw ResultSet exception - before start of result set error. 
                rs.next();
                // Get the new row id.
                int generatedId = rs.getInt(1);
                userAccountDto.setId(generatedId);
    
            } catch (SQLException ex) {
                this.printSqlException(ex);
            }
        }
    
        // Update user account object.
        public void updateUserAccount(UserAccountDTO userAccountDto){
    
            Statement stmt;
            try {
                stmt = getDatabaseConnection().createStatement();
    
                StringBuffer strBuf = new StringBuffer();
    
                strBuf.append("update user_account set user_name = '");
                strBuf.append(userAccountDto.getUserName());
                strBuf.append("', password = '");
                strBuf.append(userAccountDto.getPassword());
                strBuf.append("', email = '");
                strBuf.append(userAccountDto.getEmail());
                strBuf.append("' where id = ");
                strBuf.append(userAccountDto.getId());
    
                stmt.executeUpdate(strBuf.toString());
    
                connection.commit();
    
            } catch (SQLException ex) {
                this.printSqlException(ex);
            }
        }
    
        // Delete user account object.
        public void deleteUserAccount(String userName){
    
            Statement stmt;
            try {
                stmt = getDatabaseConnection().createStatement();
    
                StringBuffer strBuf = new StringBuffer();
    
                strBuf.append("delete from user_account");
                strBuf.append(" where user_name = '");
                strBuf.append(userName);
                strBuf.append("'");
    
                stmt.executeUpdate(strBuf.toString());
    
                connection.commit();
    
            } catch (SQLException ex) {
                this.printSqlException(ex);
            }
        }
    
        // Select user account object.
        public List<UserAccountDTO> selectUserAccount(){
    
            List<UserAccountDTO> ret = new ArrayList<UserAccountDTO>();
    
            Statement stmt;
            try {
                stmt = getDatabaseConnection().createStatement();
    
                String sql = "select id, user_name, password, email from user_account";
    
                ResultSet rs = stmt.executeQuery(sql);
    
                if(rs!=null)
                {
                    while(rs.next()) {
                        UserAccountDTO dto = new UserAccountDTO();
    
                        int id = rs.getInt("id");
                        dto.setId(id);
    
                        String userName = rs.getString("user_name");
                        dto.setUserName(userName);
    
                        String password = rs.getString("password");
                        dto.setPassword(password);
    
                        String email = rs.getString("email");
                        dto.setEmail(email);
    
                        StringBuffer strBuf = new StringBuffer();
                        strBuf.append("id = ");
                        strBuf.append(id);
                        strBuf.append(", userName = ");
                        strBuf.append(userName);
                        strBuf.append(", password = ");
                        strBuf.append(password);
                        strBuf.append(", email = ");
                        strBuf.append(email);
    
                        System.out.println(strBuf.toString());
    
                        ret.add(dto);
                    }
                }
            } catch (SQLException ex) {
                this.printSqlException(ex);
            }finally
            {
                return ret;
            }
        }
    
        // Print SQLException error message, error code and error sql state. 
        private void printSqlException(SQLException ex) {
    
            if(ex!=null)
            {
                ex.printStackTrace();
                System.out.println("Error Message : " + ex.getMessage());
                System.out.println("Error Code : " + ex.getErrorCode());
                System.out.println("SQL State : " + ex.getSQLState());
            }
        }
    
    }

1.4 UserAccountDTO Java File.

  1. This class object represents one row in table user_account.
  2. UserAccountDTO.java
    package com.dev2qa.dto;
    
    public class UserAccountDTO {
    
        private int id;
    
        private String userName;
    
        private String password;
    
        private String email;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
    }

1.5 Spring Bean Definition Xml File.

  1. This is the spring bean configuration file. It is saved in the src/main/resources folder.
  2. ApplicationContextBeans.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-3.2.xsd">
    
        <!-- Define PropertyPlaceholderConfigurer bean. -->
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <!-- Set jdbc.properties file in locations attribute. The jdbc.properties file is also saved in src/main/resources folder. -->
            <property name="locations" value="classpath:jdbc.properties" />
        </bean>
    
        <!-- Define common dbcp datasource bean. -->
        <bean id="ds" destroy-method="close" class="org.apache.commons.dbcp2.BasicDataSource">
            <!-- Get property value use ${} operator (${jdbc.driverClassName}). -->
            <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>
    
        <!-- Define UserAccountDAO bean. -->
        <bean id="userAccountDao" class="com.dev2qa.dao.UserAccountDAO">
            <!-- Set above DataSource object in UserAccountDAO constructor. -->
            <constructor-arg name="dataSource" ref="ds"/>
        </bean>
    
    </beans>

1.6 External Properties File.

  1. The jdbc.properties file is saved in the src/main/resources folder also. The properties file content is key=value pair. One line represents one JDBC connection property.
  2. Please note the jdbc.url value format is jdbc:mysql://host_name:port_number/database_name?useSSL=false, useSSL=false can avoid Establishing SSL connection without server’s identity verification is not recommended warn message.
    jdbc.driverClassName=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/dev2qa?useSSL=false
    jdbc.username=test
    jdbc.password=999888

1.7 pom.xml File.

  1. pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.springframework.samples</groupId>
        <artifactId>ReadExternalPropertiesXml</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <properties>
    
            <!-- Generic properties -->
            <java.version>1.6</java.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    
            <!-- Spring -->
            <spring-framework.version>3.2.3.RELEASE</spring-framework.version>
    
    
        </properties>
    
        <dependencies>
    
            <!-- Spring depend jar. -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring-framework.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring-framework.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring-framework.version}</version>
            </dependency>
    
            <!-- MySQL jdbc jar. -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.12</version>
            </dependency>
    
            <!-- Commons dbcp jar. -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-dbcp2</artifactId>
                <version>2.1.1</version>
            </dependency>
    
    
        </dependencies>
    </project>

1.8 Example Execution Results.

  1. Below is the above example executing output.
    ================= Add first user Jerry ==================
    insert into user_account(user_name, password, email) values ('Jerry','999999','[email protected]')
    id = 15, userName = Jerry, password = 999999, email = [email protected]
    ================= Update Jerry password and email ==================
    id = 15, userName = Jerry, password = 888888, email = [email protected]
    ================= Add second user Richard ==================
    insert into user_account(user_name, password, email) values ('Richard','111111','[email protected]')
    id = 15, userName = Jerry, password = 888888, email = [email protected]
    id = 16, userName = Richard, password = 111111, email = [email protected]
    ================ Delete user Richard ===================
    id = 15, userName = Jerry, password = 888888, email = [email protected]

2. Read External Properties File Use Java Annotation.

  1. Create the spring bean configuration java file and annotate the configuration java class with @PropertySource(“classpath:jdbc.properties”) to specify the properties file location.
  2. Create a PropertySourcesPlaceholderConfigurer spring bean instance in the above spring beans configuration java class file.
  3. Then you can read the properties in java code use @Value(${“property_key_name”}) to inject the property value to the class instance variable.

2.1 Read External Properties Use Java Annotation Example Project.

  1. Below is the example project source files list.
    C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\SPRINGBOOT\READEXTERNALPROPERTIESANNOTATION
    │   pom.xml
    │
    ├───src
    │   └───main
    │       ├───java
    │       │   └───com
    │       │       └───dev2qa
    │       │           ├───config
    │       │           │       ApplicationBeansConfig.java
    │       │           │
    │       │           ├───dao
    │       │           │       UserAccountDAO.java
    │       │           │
    │       │           ├───dto
    │       │           │       UserAccountDTO.java
    │       │           │
    │       │           └───test
    │       │                   TestUserAccountDAO.java
    │       │
    │       └───resources
    │               jdbc.properties
  2. The java annotation version example is similar to the XML configuration version. The only difference is two files, ApplicationBeansConfig.java and TestUserAccountDAO.java. Other files are the same.

2.2 Spring Beans Definition Java File.

  1. ApplicationBeansConfig.java
    package com.dev2qa.config;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp2.BasicDataSource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
    
    import com.dev2qa.dao.UserAccountDAO;
    
    /* PropertySource annotation defines the external properties file location, in this case the properties file located in classpath. 
     * Then PropertySourcesPlaceholderConfigurer class will read and parse the properties in key value pair saved in this file.
     *  */
    @PropertySource("classpath:jdbc.properties")
    @Configuration
    public class ApplicationBeansConfig {
    
        // Inject related properties value to instance variables.
        @Value("${jdbc.username}")
        private String username;
    
        @Value("${jdbc.password}")
        private String password;
    
        @Value("${jdbc.driverClassName}")
        private String driverClassName;
    
        @Value("${jdbc.url}")
        private String jdbcURL;
    
        /* Define PropertySourcesPlaceholderConfigure spring bean. */
        @Bean
        public static PropertySourcesPlaceholderConfigurer getPropertySourcePlaceholderConfig() {
            PropertySourcesPlaceholderConfigurer ret = new PropertySourcesPlaceholderConfigurer();
            return ret;
        }
    
        /* Define datasource object spring bean.*/
        @Bean
        public DataSource getDataSource() {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driverClassName);
            dataSource.setUrl(jdbcURL);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        }
    
        /* Define UserAccountDAO spring bean. */
        @Bean(name="userAccountDao")
        public UserAccountDAO getUserAccountDao(DataSource dataSource) {
            return new UserAccountDAO(dataSource);
        }
    
    }

2.3 Example Main Java File.

  1. The difference between the java annotation and XML configuration version is how to get the userAccountDao spring bean by java annotation config.
  2. TestUserAccountDAO.java
    package com.dev2qa.test;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.dev2qa.config.ApplicationBeansConfig;
    import com.dev2qa.dao.UserAccountDAO;
    import com.dev2qa.dto.UserAccountDTO;
    
    public class TestUserAccountDAO {
    
        public static void main(String[] args) {
    
            // Get spring beans context object.
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(ApplicationBeansConfig.class);
            context.refresh();
    
            // Get Spring UserAccountDAO bean.
            UserAccountDAO userAccountDao = (UserAccountDAO)context.getBean("userAccountDao");
    
            // Create a UserAccountDTO object.
            UserAccountDTO dto = new UserAccountDTO();
    
            System.out.println("================= Add first user Jerry ==================");
            // Add the first user account dto.
            dto.setUserName("Jerry");
            dto.setPassword("999999");
            dto.setEmail("[email protected]");
            userAccountDao.addUserAccount(dto);
            // Show the first user data.
            userAccountDao.selectUserAccount();
         
            ......
    
        }
    
    }

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.