Grimbo
Grimbo

Reputation: 237

Using maven profiles to configure code based a Spring application

I have a Spring application which is complete code based configured. And I am trying to combine maven profiles to setup my db connections. I defined some properties for a local, live and staging issues. Now I try to get control over maven profiles. Every profil defines my MySql db connection params. Here my current setup:

local.properties-file:

mysql.username=test
mysql.password=test
mysql.databaseUrl=jdbc:mysql://localhost:3306/test
mysql.databaseDriver=com.mysql.jdbc.Driver

pom.xml

...
<profiles>
        <profile>
            <id>live</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <filterFile>src/main/config/live.properties</filterFile>
            </properties>
        </profile>
        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <filterFile>src/main/config/local.properties</filterFile>
            </properties>
        </profile>
        <profile>
            <id>staging</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <filterFile>src/main/config/staging.properties</filterFile>
            </properties>
        </profile>
    </profiles>
...

ApplicationConfig

...
@Value("${mysql.username}")
    private String username;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername(username);
        ..

        return dataSource;
    }
...

Problem here is that my properties aren't loaded!

Upvotes: 0

Views: 1091

Answers (1)

beerbajay
beerbajay

Reputation: 20270

You are setting a property called filterFile during the maven build, but you actually need to get the value into your application, which you'll then have to use to look up the file to load.

A potentially better way of doing this is to define the variable values as properties in your pom:

<profiles>
    <profile>
        <id>live</id>
        <activation>
            <activeByDefault>false</activeByDefault>
        </activation>
        <properties>
            <mysql.username>test</mysql.username>
            <mysql.password>test</mysql.password>
            <mysql.databaseUrl>jdbc:mysql://localhost:3306/test</mysql.databaseUrl>
        </properties>
    </profile>
    <!-- ... -->
</profiles>

Then enable resource filtering:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

In a file, e.g. persistence.properties:

mysql.username=${mysql.username}
mysql.password=${mysql.password}
mysql.databaseUrl=${mysql.databaseUrl}
mysql.databaseDriver=com.mysql.jdbc.Driver

Finally, load the properties file and create your datasource:

@PropertySource({"classpath:persistence.properties"})
public class DatabaseConfig {
    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername(env.getProperty("mysql.username"));
        // ...
        return dataSource;
    }
}

Upvotes: 2

Related Questions