Profiles in Spring Framework :
Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments like Prod, Dev and QA and any class having @Component
or @Configuration
can be marked with @Profile
Lets create a spring boot sample projects to demonstrate profiles in spring framework…Here i am using Spring Initializr to create the project :
Now click on GENERATE and it will start the download and will be downloaded as a zip file now extract it and import this maven project in your favorite ide here i am using STS as an IDE
Now lets create three schema in our database i am using Mysql as database so local, dev and prod are three schemas which i have created in Mysql workbench.
CREATE DATABASE local;
CREATE DATABASE dev;
CREATE DATABASE prod;
Now open the application.properties file and provide the database related information :
application.properties :
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/local
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
#Set profile to switch from one env to another like local, prod, dev and etc
spring.profiles.active=local
Now create two more properties files in src/main/resources for dev and prod environments separately like this : application-dev.properties
and application-prod.properties and provide the database related details :
application-dev.properties :
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/dev
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
application-prod.properties :
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/prod
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
Now create a model class : Here is a User class for demonstration :
package com.abhishek.spring.profiles.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
}
Now create a dao or repository to fetch details from DB:
package com.abhishek.spring.profiles.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abhishek.spring.profiles.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
}
Next step is to create a service layer class :
package com.abhishek.spring.profiles.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import com.abhishek.spring.profiles.model.User;
import com.abhishek.spring.profiles.repo.UserRepository;
@Service
@Profile(value = {"local","dev","prod"})
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAllUser() {
return userRepository.findAll();
}
}
Here You can see i have used @Profile and provided all the different evironments to access the data so i can use any of these environments to fetch data from the databases :
Now lets create a controller class to test the data using postman :
package com.abhishek.spring.profiles.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.abhishek.spring.profiles.model.User;
import com.abhishek.spring.profiles.service.UserService;
@RestController
@RequestMapping("/api/v1")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public List<User> getAllUsers() {
return userService.findAllUser();
}
}
Now open the main or root application.properties file :
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/local
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
#Set profile to switch from one env to another like local, prod, dev and etc
spring.profiles.active=local
So here you can see the profile which im using is local which is configured using spring.profiles.active=local so it will fetch data from local database which we created earlier in this section..
So now lets go to the postman and hit the endpoint but before that lets insert some data in these three databases so for demo purpose i have inserted some rows in these databases which are :
Now in main application.properties file we are using profile as local
now start the spring boot application so when we will hit the endpoint http://localhost:8080/api/v1/users it will show you all the users from local db :
[
{
"id": 1,
"name": "localuser1"
},
{
"id": 2,
"name": "localuser2"
},
{
"id": 3,
"name": "localuser3"
},
{
"id": 4,
"name": "localuser4"
},
{
"id": 5,
"name": "localuser5"
}
]
Now lets change the profile in application.properties to prod
spring.profiles.active=prod now start the spring boot application and when you will hit the same endpoint http://localhost:8080/api/v1/users then it will show you all the users from prod db
[
{
"id": 1,
"name": "produser1"
},
{
"id": 2,
"name": "produser2"
},
{
"id": 3,
"name": "produser3"
},
{
"id": 4,
"name": "produser4"
},
{
"id": 5,
"name": "produser5"
}
]
Simillarly now lets change the profile in application.properties to dev spring.profiles.active=dev now start the spring boot application and when you will hit the same endpoint http://localhost:8080/api/v1/users then it will show you all the users from dev db
[
{
"id": 1,
"name": "devuser1"
},
{
"id": 2,
"name": "devuser2"
},
{
"id": 3,
"name": "devuser3"
},
{
"id": 4,
"name": "devuser4"
},
{
"id": 5,
"name": "devuser5"
}
]
So you can see here by switching the profiles we are able to fetch data from different schemas..
Keep Learning…