Example with Spring Profiles
In continuation of the Spring Boot profiles, in this article we will walk through different use cases. We will see how to read property files and display them through a controller. We have following use cases
1)Defining and reading profile-specific beans 2) populating beans from a properties file.
Purpose
In this article, we will build a Spring Boot Application with a two-controller and 2 profile-specific configuration files.
Code structure
Technology Used
Java 11
Spring Boot 2.2.6.RELEASE
Maven 3.5.0
Eclipse IDE
Spring Boot 2.2.6.RELEASE
Maven 3.5.0
Eclipse IDE
Application details
This application we have one controller EmailController which shows some data to the response. These data are collected from different Java classes. Each java class is populated by Spring in a different way.
PaymentProperties: This defines a bean-based on profile. When we read the bean PaymentProp from EmailController it shows the data based on the active profile.
MailSenderProperties: It is populated by the active profile property file.
ContactProperties and AddressProperties: These objects are populated from the respective properties file and have nothing to do with an active profile.
Code details
pom.file
<?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>
<artifactId>bootng-springboot-profiles</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>com.bootng Springboot Profile</name>
<description>com.bootng Springboot Profile</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Application Class
@ComponentScan({"com.bootng", "com.bootng.service"})
@SpringBootApplication
public class RestApplication {
private static final Logger log = LoggerFactory.getLogger(RestApplication.class);
public static void main(String args[]) {
log.info("about to call RestApplication.run()");
application.run(args);
log.info("completed executing RestApplication.run()");
}
}
EmailController
package com.bootng;
@Controller
public class EmailController {
@Autowired
public MailSenderProperties mailSender;
@Autowired
private ContactProperties contact;
@Autowired
private AddressProperties address;
@Autowired
private ApplicationContext applicationContext;
@Value("${appserver.version}")
private String paymentServerVer;
@RequestMapping(value = {"/details"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity <String> paymentInfo() {
//Get the Bean with name PaymentProp
HashMap<String, String> paymentProp = (HashMap<String, String>) applicationContext.getBean("PaymentProp");
//Get the payment Server version from application.properties file
String paymentInfo ="\nPayment Server Version:= " + paymentProp.toString();
String smtpInfo = "\n Mail Server SMTP Host: " + mailSender.getSmtpHost() + " SMTP Port:"
+ mailSender.getSmtpPort();
String info = "\nContactInfo From=" + contact.getFrom() + " Email=" + contact.getFromEmail();
String addressInfo = "\n AddressInfo Street=" + address.getStreet() +
" City=" + address.getCity() +
" State=" + address.getState() +
" Zip=" + address.getZip();
String result = paymentInfo + smtpInfo + info + addressInfo;
return new ResponseEntity<String>(result, HttpStatus.OK);
}
@RequestMapping(value = {"/smtp"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity<String> sendEmail() {
String result = "<br>Mail Server SMTP Host: " + mailSender.getSmtpHost() + " SMTP Port:"
+ mailSender.getSmtpPort();
return new ResponseEntity<String>("email sent" + result, HttpStatus.OK);
}
@RequestMapping(value = {"/address"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity <String> getAddress() {
String info = "From=" + contact.getFrom() + " Email=" + contact.getFromEmail();
String addressInfo = " Street=" + address.getStreet() +
" City=" + address.getCity() +
" State=" + address.getState() +
" Zip=" + address.getZip();
return new ResponseEntity<String>(info + addressInfo, HttpStatus.OK);
}
}
PaymentProperties
@Configuration
public class PaymentProperties {
@Profile("dev")
@Bean(name="PaymentProp")
public HashMap<String, String> getPaymentServerDev() {
HashMap<String, String> paymentMethod = new HashMap<>();
paymentMethod.put("Currency", "USD");
paymentMethod.put("ChargePercentage", "1");
paymentMethod.put("Gateway", "BOA");
return paymentMethod;
}
@Profile("prod")
@Bean(name="PaymentProp")
public HashMap<String, String> getPaymentServerProd() {
HashMap<String, String> paymentMethod = new HashMap<>();
paymentMethod.put("Currency", "Pound");
paymentMethod.put("ChargePercentage", "4");
paymentMethod.put("Gateway", "BankOfEngland");
return paymentMethod;
}
}
MailSenderProperties
@Component
@PropertySource("classpath:application-${spring.profiles.active}.properties")
public class MailSenderProperties {
@Value("${mail.smtp.host}")
private String smtpHost;
@Value("${mail.smtp.port}")
private Integer smtpPort;
public String getSmtpHost() {
return smtpHost;
}
public void setSmtpHost(String smtpHost) {
this.smtpHost = smtpHost;
}
public Integer getSmtpPort() {
return smtpPort;
}
public void setSmtpPort(Integer smtpPort) {
this.smtpPort = smtpPort;
}
}
ContactProperties
@Component
@ConfigurationProperties(prefix = "contact")
@PropertySource("classpath:office-address.properties")
@Validated
public class ContactProperties {
@NotNull
private String from;
@Email
private String fromEmail;
@Value("${contact.fromTwitter}")
private String twitterHandle;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getFromEmail() {
return fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getTwitterHandle() {
return twitterHandle;
}
public void setTwitterHandle(String twitterHandle) {
this.twitterHandle = twitterHandle;
}
}
AddressProperties
@Component
@PropertySource("classpath:office-address.properties")
@Validated
public class AddressProperties {
@Value("${address.street}")
private String street;
@Value("${address.city}")
private String city;
@Value("${address.state}")
private String state;
@NotNull
@Value("${address.zip}")
private String zip;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
application-dev.properties
logging.level.root=info
mail.smtp.host=mail.dev.com
mail.smtp.port=7777
mail.smtp.user=test_dev
application-prod.properties
logging.level.root=info
mail.smtp.host=mail.prod.com
mail.smtp.port=8888
mail.smtp.user=prod_user
Run with profile prod
Run the application with prod profile set to active and then when the application is started, go to http://localhost:8080/details
mvn spring-boot:run -Dspring-boot.run.profiles=prod
Browser Output
Payment Server Version:= {Gateway=BankOfEngland, Currency=Pound, ChargePercentage=4}
Mail Server SMTP Host: mail.prod.com SMTP Port:8888
ContactInfo From=admin Email=admin@bootng.com
AddressInfo Street=1901 Palo Alto Avenue City=Palo Alto State=California Zip=950441
Run with profile dev
Stop the running application. And then restart with profile = dev
mvn spring-boot:run -Dspring-boot.run.profiles=dev
Browser Output
Payment Server Version:= {Gateway=BOA, Currency=USD, ChargePercentage=1}
Mail Server SMTP Host: mail.dev.com SMTP Port:7777
ContactInfo From=admin Email=admin@bootng.com
AddressInfo Street=1901 Palo Alto Avenue City=Palo Alto State=California Zip=950441
Download Source code
git clone git@github.com:bootng/spring-boot-references.git
cd sping-boot-profiles
mvn clean install
mvn spring-boot:run -Dspring-boot.run.profiles=dev
Conclusion
This article shows different ways we can use Profiles in Application.
We can see different values in the Controller output based on the profile.
We can have multiple profiles active, but this article deals with only setting one profile at a time.
Can you guess what will happen with this application and multiple profiles set active?
No comments :
Post a Comment
Please leave your message queries or suggetions.
Note: Only a member of this blog may post a comment.