DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • How to Activate New User Accounts by Email
  • How To Build Web Service Using Spring Boot 2.x
  • Spring Boot Pet Clinic App: A Performance Study
  • Improving Backend Performance Part 1/3: Lazy Loading in Vaadin Apps

Trending

  • DuckDB for Python Developers
  • Context Is the New Schema
  • Building a Skill-Based Agentic Reviewer with Claude Code: A Practical Guide Using Skills.MD, MCP Servers, Tools, and Tasks
  • Java Backend Development in the Era of Kubernetes and Docker
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Spring Config Integration With a PCF Application: A Step-by-Step Guide

Spring Config Integration With a PCF Application: A Step-by-Step Guide

A developer takes us through the process of integrating a Spring config file with a PCF application, including all the code you need to get started.

By 
Gitanjali Sahoo user avatar
Gitanjali Sahoo
·
Jan. 03, 21 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
15.0K Views

Join the DZone community and get the full member experience.

Join For Free

Why Spring Configuration? 

Spring Cloud Config provides support for externalized configuration in a distributed system. It allows you to dynamically push updates to configuration properties to the application without needing to restart or redeploy.

Step-by-Step Guide to Integrate With a PCF Application

Step 1: Add a Maven Dependency

XML
 




xxxxxxxxxx
1
23


 
1
<dependency>
2

          
3
               <groupId>io.pivotal.spring.cloud</groupId>
4

          
5
<artifactId>spring-cloud-services-starter-config-client</artifactId>
6

          
7
             </dependency>
8

          
9
              <dependency>
10

          
11
                    <groupId>org.springframework.cloud</groupId>
12

          
13
                    <artifactId>spring-cloud-starter-config</artifactId>
14

          
15
             </dependency>
16

          
17
             <dependency>
18

          
19
                    <groupId>org.springframework.boot</groupId>
20

          
21
                    <artifactId>spring-boot-starter-actuator</artifactId>
22

          
23
             </dependency>


pom.xml 

XML
 




xxxxxxxxxx
1
113


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
    <modelVersion>4.0.0</modelVersion>
6

          
7
    <groupId>gsahoo.demo</groupId>
8
    <artifactId>aSpringConfigDemo</artifactId>
9
    <version>1.0.0</version>
10
    <packaging>jar</packaging>
11

          
12
    <name>aspringconfig-demo</name>
13
    <description>Spring Boot with spring config</description>
14
    <parent>
15
        <groupId>org.springframework.boot</groupId>
16
        <artifactId>spring-boot-starter-parent</artifactId>
17
        <version>2.3.0.RELEASE</version>
18
        <relativePath ></relativePath> <!-- lookup parent from repository -->
19
    </parent>
20

          
21
    <properties>
22
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24
        <java.version>1.8</java.version>
25
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
26
    </properties>
27
    <dependencies>
28
        <dependency>
29
            <groupId>junit</groupId>
30
            <artifactId>junit</artifactId>
31
            <version>3.8.1</version>
32
            <scope>test</scope>
33
        </dependency>
34

          
35
        <dependency>
36
            <groupId>org.springframework.boot</groupId>
37
            <artifactId>spring-boot-starter</artifactId>
38
        </dependency>
39

          
40

          
41

          
42
        <dependency>
43
            <groupId>com.fasterxml.jackson.core</groupId>
44
            <artifactId>jackson-databind</artifactId>
45
        </dependency>
46
        <dependency>
47
            <groupId>org.projectlombok</groupId>
48
            <artifactId>lombok</artifactId>
49
        </dependency>
50

          
51

          
52
        <dependency>
53
            <groupId>io.springfox</groupId>
54
            <artifactId>springfox-swagger2</artifactId>
55
            <version>2.6.1</version>
56
        </dependency>
57

          
58
        <dependency>
59
            <groupId>io.springfox</groupId>
60
            <artifactId>springfox-swagger-ui</artifactId>
61
            <version>2.6.1</version>
62
        </dependency>
63
        <dependency>
64
            <groupId>org.springframework.boot</groupId>
65
            <artifactId>spring-boot-starter-web</artifactId>
66
        </dependency>
67
        <dependency>
68
            <groupId>io.pivotal.spring.cloud</groupId>
69
            <artifactId>spring-cloud-services-starter-config-client</artifactId>
70
        </dependency>
71

          
72
        <dependency>
73
            <groupId>org.springframework.cloud</groupId>
74
            <artifactId>spring-cloud-starter-config</artifactId>
75
        </dependency>
76
        <dependency>
77
            <groupId>org.springframework.boot</groupId>
78
            <artifactId>spring-boot-starter-actuator</artifactId>
79
        </dependency>
80

          
81
    </dependencies>
82
    <dependencyManagement>
83
        <dependencies>
84

          
85
            <dependency>
86
                <groupId>org.springframework.cloud</groupId>
87
                <artifactId>spring-cloud-dependencies</artifactId>
88
                <version>${spring-cloud.version}</version>
89
                <type>pom</type>
90
                <scope>import</scope>
91
            </dependency>
92
            <dependency>
93
                <groupId>io.pivotal.spring.cloud</groupId>
94
                <artifactId>spring-cloud-services-dependencies</artifactId>
95
                <version>2.2.1.RELEASE</version>
96
                <type>pom</type>
97
                <scope>import</scope>
98
            </dependency>
99

          
100
        </dependencies>
101
    </dependencyManagement>
102
    <build>
103
        <plugins>
104
            <plugin>
105
                <groupId>org.springframework.boot</groupId>
106
                <artifactId>spring-boot-maven-plugin</artifactId>
107
            </plugin>
108
        </plugins>
109
    </build>
110
</project>


Step 2: Add refreshscope and EnableAutoConfiguration to the Model Class

Java
 




x


 
1
package gsahoo.demo.model;
2

          
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5
import org.springframework.cloud.context.config.annotation.RefreshScope;
6
import org.springframework.context.annotation.Configuration;
7
import org.springframework.stereotype.Component;
8

          
9
@Configuration
10

          
11
@EnableAutoConfiguration
12

          
13
@RefreshScope
14

          
15
@Component
16

          
17
public class Person {
18

          
19
    @Value("${person.company}")
20

          
21
    String company = null;
22

          
23
    public void setCompany(String company) {
24

          
25
        this.company = company;
26

          
27
    }
28

          
29
    public String getCompany() {
30

          
31
        return company;
32

          
33
    }
34

          
35
}


If you are autowiring this model object in any other class then make sure to add refreshscope to that class as well.

Step 3: Enable Actuator Endpoints 

By default only the /health and /info endpoints are enabled. Enable other endpoints one-by-one by declaring explicitly or enabling them all by using a wildcard character.

Add the below line to your application.properties file to enable the /refresh endpoint:

management.endpoints.web.exposure.include=refresh 

You may additionally disable default security for this tutorial by adding the below code to application.properties file:

management.security.enabled=false

or by adding the below lines of code to your Spring Boot application:

Java
 




xxxxxxxxxx
1
16


 
1
package gsahoo.demo;
2

          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
6
import org.springframework.cloud.context.config.annotation.RefreshScope;
7
import org.springframework.context.annotation.Bean;
8
import org.springframework.context.annotation.Configuration;
9
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
10

          
11
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class , ManagementWebSecurityAutoConfiguration.class})
12
public class aSpringConfigDemoApplication {
13

          
14
    public static void main(String[] args) {
15
        SpringApplication.run(aSpringConfigDemoApplication.class, args);
16
    }


Note: For this tutorial, security is disabled in order to access actuator endpoints. In a prod environment you must consider security.

Step 4: Add a Property to the application.properties File

person.company=ABC

Step 5: Build and Deploy the App to Cloud Foundry

cf push

Run the above command from the root folder of the application. Use the manifest.yml file to declare your app name:

YAML
 




xxxxxxxxxx
1
10
9


 
1
---
2
applications:
3
- name: aspringconfig-demo
4
  memory: 1G
5
  instances: 1
6
 
7
  path: target/aSpringConfigDemo-1.0.0.jar
8
  buildpack: <provide-your-buildpack-version>
9
  disk_quota: 2G


Step 6: Create an Instance of Spring Server in CF

Select Spring Config from PCF Marketplace to create an instance.

Use JSON to enter GitLab information:

Use the below format to enter your JSON data:

  • uri  - the HTTP URL to the GitLab URL.
  • searchPaths - the GitLab URL subfolder that the application should search through for the config file. If this is not specified then the app will search in the current folder specified by the "uri" attributes. 
  • username  - user account to login to the above GitLab URL. It must have read access to the GitLab URL from where it will read the config file.
  • password - password attached to the GitLab user name.
  • label - specify which GitLab branch to use to read the config file. If not specified then it defaults to the "master branch."

Step 7: Bind Your App to the Above Service Instance

If the service instance is created successfully then it can be viewed from the Service Instance manager:

If it is successfully bound to the app then you should see a log entry as below:

Plain Text
 




xxxxxxxxxx
1


 
1
--- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-https:............................


Testing

Step 1: Add/Update the Property Value in a Config File in GitLab 

  1. Create a file named aspringconfig-demo-cloud.properties (filename follows the naming convention <application_name>-<active-profile-name>.properties) under the folder that was provided in the serachPaths property above. Be sure to put this file under the GitLab URL provided in the uri property above.
  2. Add a new value for person.company e.g. person.company=XYZ.
  3. Commit the file to GitLab.

Step 2: Call the Actuator/Refresh Endpoint to Refresh/Reload the Property

The property that was changed in Step 1 will be returned by this call. Your application now has a reference to the updated value:

How Does it Work Internally?

When a Spring bean is declared with @refreshscope, a proxy wrapper gets created for that bean. This proxy class interacts with underlying an bean class to return the value.

When a refresh event occurs in Spring:

  1. invalidate the proxy class.
  2. reload the config file.
  3. recreate the underlying bean class.
  4. return the new value.

Though this feature has the benefit of updating to a new value at runtime, care should be taken considering that on a refresh event Spring beans become invalid until re-creation. If a user is using the bean at that time they may experience a 500 error or similar error. 

File Precedence

  • Precedence rules for GitLab config files are also the same as in a regular Spring Boot application: 
    • Active profiles take precedence over defaults.
    • Profile-specific property files override the application-named property file which overrides non-specific property files such as the application.properties file or application.yml file.

If the app name is "foo" and profile name is "dev" then foo-dev.properties overrides the foo.properties file. The foo.properties file overrides the application.properties file.

When multiple files are specified, the latter ones can override the values of earlier ones.

References

http://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html

https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html

Spring Framework application Spring Boot GitLab Property (programming) Integration app

Opinions expressed by DZone contributors are their own.

Related

  • How to Activate New User Accounts by Email
  • How To Build Web Service Using Spring Boot 2.x
  • Spring Boot Pet Clinic App: A Performance Study
  • Improving Backend Performance Part 1/3: Lazy Loading in Vaadin Apps

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook