Spring Boot Managing Profiles with @Profile Annotation Example

摘要: Spring Profiles provides a way to segregate parts of your application configuration and make it only available in certain environments. This is particularly useful when configuring different environments like development and/or production. In the following tutorial we demonstrate how to manage spring profiles with @Profile annotation.

Spring Profiles provides a way to segregate parts of your application configuration and make it only available in certain environments. This is particularly useful when configuring different environments like development and/or production. In the following tutorial we demonstrate how to manage spring profiles with @Profile annotation.

Project Structure

Our application has the following project structure. Note: we have four different application-${env}.yml property files. Each file represents properties for a different environment, except the application-common.yml which is included in every property file.

Maven Dependencies

We use Apache Maven to manage our project’s dependencies. As we are writing JUnit tests, we also included the org.springframework.boot:spring-boot-starter-test dependency.

<?xml version="1.0" encoding="UTF-8"?>
<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>com.memorynotfound.springboot</groupId>
    <artifactId>profiles</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <url>https://memorynotfound.com</url>
    <name>Spring Boot - ${project.artifactId}</name>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
    </parent>

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

    <build>
    	<finalName>l;spring-boot-profile-example</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Application Environment Properties

We are configuring three environments: default, dev and prod. Each of these environments will include the application-common.yml properties file. We use different environment profiles to illustrate how to manage spring profiles using @Profile annotation.

The application-common.yml is used for common application properties.

app:
  name: common-profile-name

The application-default.yml has the following content.

spring:
    profiles:
        active:
            - default
        include: common
app:
  email: [email protected]

The application-dev.yml has the following content.

spring:
    profiles:
        active:
            - dev
        include: common
app:
  email: [email protected]

The application-prod.yml has the following content.

spring:
    profiles:
        active:
            - prod
        include: common
app:
  email: [email protected]

Configurable Application Properties

Depending on the active spring profile usually set by spring.profiles.active, spring will load different configuration properties.

package com.memorynotfound.springboot;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("app")
public class ApplicationProperties {

    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "ApplicationProperties{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

Spring Boot – @Profile Example

We can also manage different spring components using the @Profile annotation.

package com.memorynotfound.springboot;

public interface Configuration {
    String getName();
}

The @Profile annotation indicates which component’ll be injected. Here we added two profiles: dev and default.

package com.memorynotfound.springboot;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile({"dev", "default"})
public class DevelopmentConfiguration implements Configuration {

    @Override
    public String getName() {
        return "development profile";
    }
}

The @Profile annotation indicates which component’ll be injected. Here we added one profile: prod.

package com.memorynotfound.springboot;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile({"prod"})
public class ProductionConfiguration implements Configuration {

    @Override
    public String getName() {
        return "production profile";
    }
}

Bootstrap Spring Boot Application

We wrote a simple spring boot application that’ll print the properties configured in the active profile.

package com.memorynotfound.springboot;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import javax.annotation.PostConstruct;

@SpringBootApplication
@EnableConfigurationProperties(ApplicationProperties.class)
public class Application {

    private static Logger logger = LoggerFactory.getLogger(Application.class);

    @Autowired
    private ApplicationProperties properties;

    @Autowired
    private Configuration configuration;

    public static void main(String... args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @PostConstruct
    private void init(){
        logger.info("Spring Boot - active profile: " + configuration.getName());
        logger.info("Spring Boot - Choosing Your Profile and @Profile annotation example");
        logger.info(properties.toString());

    }

}

Programatically Setting Profiles

If you want, you can set an additional spring profile programatically.

public static void main(String... args) throws Exception {
    SpringApplication app = new SpringApplication(Application.class);
    app.setAdditionalProfiles("common");
    app.run(args);
}

Building and Running Spring Boot Application

### Building application
mvn clean package

### Running with maven
mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=prod"

### Running with java
java -jar spring-boot-profile-example.jar --spring.profiles.active=prod

Console Output

The previous application run with the argument spring.profiles.active=prod prints the following output to the console.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.3.RELEASE)

2017-05-30 13:48:26.808  INFO 26463 --- [           main] c.memorynotfound.springboot.Application  : The following profiles are active: common,dev
2017-05-30 13:48:27.624  INFO 26463 --- [           main] c.memorynotfound.springboot.Application  : Spring Boot - active profile: production profile
2017-05-30 13:48:27.624  INFO 26463 --- [           main] c.memorynotfound.springboot.Application  : Spring Boot - Choosing Your Profile and @Profile annotation example
2017-05-30 13:48:27.624  INFO 26463 --- [           main] c.memorynotfound.springboot.Application  : ApplicationProperties{name='common-profile-name', email='[email protected]'}

Unit Testing Spring Profiles with JUnit

We previously saw how to use spring profiles to manage environment properties. In the following section we’ll write unit tests using JUnit and spring-boot-test.

Spring Boot – JUnit profiles @ActiveProfiles

We can annotate the class using @ActiveProfiles to register the default active profile.

package com.memorynotfound.springboot.test;

import com.memorynotfound.springboot.Configuration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;


@SpringBootTest
@ActiveProfiles("dev")
@RunWith(SpringRunner.class)
public class ConfigurationTest {

    @Autowired
    Configuration configuration;

    @Test
    public void testDevelopmentProfile(){
        String name = configuration.getName();
        assertThat(name).contains("development");
    }
}

Spring Boot – JUnit Application

Running the application we can pass the spring.profiles.active using different methods. In the fist test, we don’t provide any profile. Spring’ll automatically use the default profile, when no other profile is set. In the next test, we set the spring.profiles.active property using a system variable. In the last test we pass the --spring.profiles.active=prod argument to the main method of the application.

package com.memorynotfound.springboot.test;

import com.memorynotfound.springboot.Application;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;
import static org.assertj.core.api.Assertions.assertThat;

public class ApplicationTest {

    @Rule
    public OutputCapture outputCapture = new OutputCapture();

    @Before
    public void before() {
        System.clearProperty("spring.profiles.active");
    }

    @Test
    public void testDefaultProfile() throws Exception {
        Application.main();
        assertThat(getConsoleOutput())
                .contains("[email protected]")
                .contains("common-profile-name");
    }

    @Test
    public void testDevelopmentProfile() throws Exception {
        System.setProperty("spring.profiles.active", "dev");
        Application.main();
        assertThat(getConsoleOutput())
                .contains("[email protected]")
                .contains("common-profile-name");
    }

    @Test
    public void testProductionProfile() throws Exception {
        Application.main("--spring.profiles.active=prod");
        assertThat(getConsoleOutput())
                .contains("[email protected]")
                .contains("common-profile-name");
    }


    private String getConsoleOutput(){
        return outputCapture.toString();
    }
}

Download

Download it – [email protected]

上一篇: Spring Boot Spring Data JPA with Hibernate and H2 Web Console
下一篇: Spring Boot @ConfigurationProperties Annotation Example
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号