What are Spring Profiles and how to use them

Keywords: Java Spring Spring Boot Profile

[copyright notice] for non-commercial purposes, indicate the source and can be reproduced freely
From: shusheng007

summary

When you first came into contact with SpringBoot, did you feel a little uncomfortable with the Profile it provided? After groping, you realized its power. Today, I will summarize the Profile and keep it as an Internet memory.

What is a Profile

Profile translated into Chinese is: profile, file. For example, Wang Ergou and Niu Cuihua each have their own profile

Cuihua's Profile:

Name: Niu Cuihua
 Gender: Female
 Hobbies: shopping

Wang Ergou's Profile:

Name: Wang Ergou
 Gender: Male
 Hobbies: programming, watching beauty

The same applies to Spring. In actual development, there will be several sets of environments such as dev, uat and prod, which share a set of code logic, but need different configurations. For example, dev environment needs to connect to the test database, while prod needs to connect to the production database, and so on.

How to use

As mentioned earlier, the main purpose of profile is to distinguish different environments and then configure different environments. So how to use it? There are two ways to use it in SpringBoot.

configuration file

In SpringBoot, the naming rules of the application.properties/application.yaml configuration file are agreed, and then the corresponding configuration file is loaded according to the currently activated profile.

application-{Yours profile}.properties/application-{Yours profile}.yaml

The following is the current demo project structure. It can be seen that there are three configuration files in the resources folder:

├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   │       ├── application-dev.yaml
│   │       ├── application-prod.yaml
│   │       ├── application.yaml

application-dev.yaml

server:
  port: 8081

application-prod.yaml

server:
  port: 8082

application.yaml

#blank

When the profile is default, only application.yaml is used, and the default Server port of SpringBoot is 8080. When the current profile is activated as dev, SpringBoot will additionally load application-dev.yaml and merge it into application.yaml. If there is the same configuration, it will be overwritten.

The following is the output when starting the project without activating the profile. You can see that the profile is default and the port of the server is 8080

2021-09-22 22:55:31.505  INFO 78078 --- [  restartedMain] t.s.s.SpringProfilesApplication  : No active profile set, falling back to default profiles: default
...
2021-09-22 22:55:33.056  INFO 78078 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

Code configuration

Using Profile through configuration file is the most common. In addition, Spring also provides an @ Profile annotation, which can use Profile through code.

Suppose we have an interface

public interface Speaker {
    String speak();
}

I need to use different beans in different environments, and use the following beans in dev environment

@Service
@Profile(value = {"dev","default"})
public class DevSpeaker implements Speaker{
    @Override
    public String speak() {
        return "I am dev speaker";
    }
}

Use the following bean s in the prod environment

@Service
@Profile("prod")
public class ProdSpeaker implements Speaker{
    @Override
    public String speak() {
        return "I am prod speaker";
    }
}

Note the annotation @ Profile of these two files

Directly inject the instance of the interface where it is used

@RestController
public class SpeakerController {
    private final Speaker speaker;

    public SpeakerController(Speaker speaker) {
        this.speaker = speaker;
    }

    @RequestMapping(method = RequestMethod.GET,path = "/speak")
    public String speaking(){
       return speaker.speak();
    }
}

How to activate

The above is how to use it, but how can we switch our current profile to dev/prod and other profiles? SpringBoot supports many ways. Let's briefly introduce several simple and common ways.

Use startup parameters

We can pass in parameters when the SpringBoot project starts. There are three kinds of parameters, and any one can be used here.

If we use Intellij IDEA, we can click Edit Configuration, open the Configurations configuration box, and select any one in the blue box below to fill in.

Using the application configuration file

You can configure the profile into the application file of the project

spring:
  profiles:
    active: dev

Use maven's profile

maven itself also supports profiles to control compilation and packaging processes. The application file of SpringBoot can read the profile defined in pom.xml to activate the corresponding profile.

  • Add profiles to the pom.xml file
<project ...>
   ...
    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <evn>dev</evn>
            </properties>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <evn>prod</evn>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
    </profiles>
    ...
 </project>

We create two Profiles, dev and profile, and then use profile as the default profile. Refresh maven after adding, and you can see that a profile entry appears in the maven window in the upper right corner of the IDE. We can check which profile to activate and remember reload.

  • Read in application.yaml
spring:
  profiles:
    active: @evn@

Note @ evn @, where evn is < evn > your profile < / evn > defined by profiles in pom.xml, and the first and second @ are the syntax for spring boot to read maven's profile.

Normally, it is OK after the above two steps. When I test, I only need the above two steps to succeed, but someone said that the following configuration needs to be added.

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

How to get active Profiles

There are two ways to get the currently active profile, through Environment or @ Value

@RestController
public class SpeakerController {
    @Value("${spring.profiles.active:}")
    private String activeProfile;
    
    private final Environment environment;
    
    public SpeakerController(Environment environment) {
        this.environment = environment;
    }

    @GetMapping("/profiles")
    public String getCurrentProfiles(){
       return String.format("adopt Environment obtain:%s | adopt@Value obtain:%s",
               Arrays.toString(environment.getActiveProfiles()),
               activeProfile);
    }
}

summary

Just say so much for the time being. Leave a message if you have any questions. If you have no questions, just like it. Go to bed...

First article and source address

Posted by d-woo on Wed, 06 Oct 2021 23:56:03 -0700