Configuration & profiles - Spring Boot application’ni turli muhitlarda boshqarish uchun ishlatiladi: local, development, test, production.
Bu bo‘lim ichida quyidagilar bor: @ConfigurationProperties, Spring Profiles, @Profile, spring.profiles.active, application-dev.yml, application-prod.yml, environment variables override.
1. Configuration nima?
Configuration - application sozlamalari.
Masalan:
server port
database URL
database username/password
JWT secret
file upload limit
logging level
external API URL
mail server configBularni kod ichiga qattiq yozish yomon.
Yomon:
String apiUrl = "https://api.example.com";
String dbPassword = "12345";Yaxshi:
app:
external-api-url: https://api.example.comKeyin Java kodda config’dan o‘qiladi.
2. application.properties va application.yml
Spring Boot’da asosiy config fayl odatda:
src/main/resources/application.propertiesyoki:
src/main/resources/application.ymlbo‘ladi.
application.properties
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/shop_db
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=validateapplication.yml
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_db
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: validateIkkalasi ham ishlaydi. Lekin katta configlarda yml o‘qishga qulayroq.
3. Nega config kerak?
Config orqali application’ni kodni o‘zgartirmasdan boshqaramiz.
Masalan local’da database:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_dbProduction’da esa:
spring:
datasource:
url: jdbc:postgresql://prod-db:5432/shop_dbKod bir xil. Faqat config boshqa.
4. Profile nima?
Profile - application qaysi muhitda ishlayotganini bildiradigan nom.
Ko‘p ishlatiladigan profile’lar:
local
dev
test
staging
prodMisol:
local → kompyuteringizda ishlaydi
dev → development server
test → test environment
prod → real userlar ishlatadigan production5. Profile fayllar
Spring Boot profile bo‘yicha alohida config fayllarni o‘qiy oladi.
src/main/resources
├── application.yml
├── application-local.yml
├── application-dev.yml
├── application-test.yml
└── application-prod.ymlAsosiy application.yml:
spring:
application:
name: shop-api
profiles:
active: localapplication-local.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_db
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: validate
show-sql: trueapplication-prod.yml:
server:
port: 8080
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: falseBu yerda production config’da password qattiq yozilmagan. Environment variable’dan olinadi.
6. spring.profiles.active
Qaysi profile ishlashini belgilaydi.
spring:
profiles:
active: devYoki command line orqali:
java -jar app.jar --spring.profiles.active=prodYoki environment variable orqali:
SPRING_PROFILES_ACTIVE=prodReal production’da ko‘pincha environment variable orqali beriladi.
7. Profile qanday ishlaydi?
Agar active profile:
spring:
profiles:
active: devbo‘lsa, Spring Boot quyidagilarni o‘qiydi:
application.yml
application-dev.ymlapplication-dev.yml ichidagi qiymatlar application.ymldagi umumiy qiymatlarni override qilishi mumkin.
Masalan:
application.yml:
server:
port: 8080application-dev.yml:
server:
port: 8081Natija:
server.port = 80818. @Value bilan config o‘qish
Eng oddiy usul - @Value.
application.yml:
app:
upload-dir: uploadsJava:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class FileService {
@Value("${app.upload-dir}")
private String uploadDir;
public void printUploadDir() {
System.out.println(uploadDir);
}
}Bu ishlaydi, lekin katta configlar uchun uncha qulay emas.
@Value kamchiligi
Agar config ko‘p bo‘lsa:
@Value("${app.jwt.secret}")
private String secret;
@Value("${app.jwt.expiration-minutes}")
private Long expirationMinutes;
@Value("${app.jwt.issuer}")
private String issuer;Kod tarqalib ketadi.
Shuning uchun @ConfigurationProperties yaxshiroq.
9. @ConfigurationProperties nima?
@ConfigurationProperties - config qiymatlarini bitta classga type-safe qilib yig‘ib beradi.
Masalan application.yml:
app:
jwt:
secret: my-secret-key
expiration-minutes: 60
issuer: shop-apiConfig class:
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "app.jwt")
public record JwtProperties(
String secret,
Long expirationMinutes,
String issuer
) {
}Lekin bu classni Spring ro‘yxatdan o‘tkazish kerak.
10. @EnableConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
public class PropertiesConfig {
}Endi JwtProperties bean bo‘ladi.
Service’da ishlatish:
import org.springframework.stereotype.Service;
@Service
public class JwtService {
private final JwtProperties jwtProperties;
public JwtService(JwtProperties jwtProperties) {
this.jwtProperties = jwtProperties;
}
public void printConfig() {
System.out.println(jwtProperties.issuer());
System.out.println(jwtProperties.expirationMinutes());
}
}11. Mutable class bilan @ConfigurationProperties
Record o‘rniga oddiy class ham ishlatish mumkin.
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "app.file")
public class FileStorageProperties {
private String uploadDir;
private Long maxSizeMb;
public String getUploadDir() {
return uploadDir;
}
public void setUploadDir(String uploadDir) {
this.uploadDir = uploadDir;
}
public Long getMaxSizeMb() {
return maxSizeMb;
}
public void setMaxSizeMb(Long maxSizeMb) {
this.maxSizeMb = maxSizeMb;
}
}application.yml:
app:
file:
upload-dir: uploads
max-size-mb: 1012. @ConfigurationProperties validation
Config ham noto‘g‘ri bo‘lishi mumkin.
Masalan JWT secret bo‘sh bo‘lsa, application start bo‘lmasin.
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@Validated
@ConfigurationProperties(prefix = "app.jwt")
public record JwtProperties(
@NotBlank(message = "JWT secret majburiy")
String secret,
@Min(value = 1, message = "Expiration kamida 1 minut bo‘lishi kerak")
Long expirationMinutes,
@NotBlank(message = "Issuer majburiy")
String issuer
) {
}Agar config noto‘g‘ri bo‘lsa, application start vaqtida xato beradi.
Bu yaxshi. Chunki production’da noto‘g‘ri config bilan application ishga tushib ketmaydi.
13. Environment variable nima?
Environment variable - server yoki OS darajasida beriladigan qiymat.
Masalan Linux’da:
export DB_URL=jdbc:postgresql://prod-db:5432/shop_db
export DB_USERNAME=shop_user
export DB_PASSWORD=super-secretSpring Boot config’da:
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}Bu production uchun muhim.
14. Default value berish
Agar environment variable yo‘q bo‘lsa, default qiymat berish mumkin.
server:
port: ${SERVER_PORT:8080}Ma’nosi:
Agar SERVER_PORT bor bo‘lsa → shuni ol
Agar yo‘q bo‘lsa → 8080 ishlatYana:
app:
file:
upload-dir: ${UPLOAD_DIR:uploads}15. Secretlarni config faylga yozmang
Yomon:
spring:
datasource:
password: my-production-password
app:
jwt:
secret: very-secret-keyNega yomon?
Gitga tushib qoladi
Developerlar ko‘radi
Repository leak bo‘lsa, production secret ochiladi
Secretni almashtirish qiyinlashadiYaxshi:
spring:
datasource:
password: ${DB_PASSWORD}
app:
jwt:
secret: ${JWT_SECRET}16. Local uchun .env ishlatish
Local development’da .env yoki IDE environment variables ishlatish mumkin.
Masalan .env:
DB_URL=jdbc:postgresql://localhost:5432/shop_db
DB_USERNAME=postgres
DB_PASSWORD=postgres
JWT_SECRET=local-secret-keyLekin .env odatda Gitga qo‘shilmaydi.
.gitignore:
.env17. @Profile nima?
@Profile - bean faqat ma’lum profile’da ishlashini bildiradi.
Masalan local profile’da test data yaratamiz:
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("local")
public class LocalDataInitializer {
public LocalDataInitializer() {
System.out.println("Local data initializer ishladi");
}
}Bu bean faqat:
spring.profiles.active=localbo‘lsa yaratiladi.
Prod’da boshqa bean
@Component
@Profile("prod")
public class ProdStartupLogger {
public ProdStartupLogger() {
System.out.println("Production mode");
}
}Bu faqat production profile’da ishlaydi.
18. @Profile bilan interface implementation tanlash
Masalan payment service local’da fake ishlasin, prod’da real ishlasin.
Interface:
public interface PaymentGateway {
void pay(BigDecimal amount);
}Local implementation:
@Service
@Profile("local")
public class FakePaymentGateway implements PaymentGateway {
@Override
public void pay(BigDecimal amount) {
System.out.println("Fake payment: " + amount);
}
}Production implementation:
@Service
@Profile("prod")
public class RealPaymentGateway implements PaymentGateway {
@Override
public void pay(BigDecimal amount) {
// real payment provider call
}
}Service:
@Service
public class OrderService {
private final PaymentGateway paymentGateway;
public OrderService(PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
}Agar active profile local bo‘lsa, FakePaymentGateway inject bo‘ladi.
Agar prod bo‘lsa, RealPaymentGateway inject bo‘ladi.
19. Profile expression
@Profile ichida expression ham yozish mumkin.
@Profile("!prod")Ma’nosi:
prod bo‘lmagan hamma profile’da ishlaydiMisol:
@Component
@Profile("!prod")
public class DebugLogger {
}Yoki:
@Profile("dev | local")Ma’nosi:
dev yoki local bo‘lsa ishlaydi20. Logging config
Local’da SQL va debug log ko‘proq kerak.
application-local.yml:
logging:
level:
root: INFO
org.hibernate.SQL: DEBUG
org.hibernate.orm.jdbc.bind: TRACEProduction’da kamroq:
logging:
level:
root: INFO
org.hibernate.SQL: WARNYomon amaliyot:
logging:
level:
root: TRACEProduction’da haddan tashqari ko‘p log performance va xavfsizlik muammo qiladi.
21. Profile bo‘yicha database config
application-local.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_db
username: postgres
password: postgresapplication-dev.yml:
spring:
datasource:
url: jdbc:postgresql://dev-db:5432/shop_db
username: ${DB_USERNAME}
password: ${DB_PASSWORD}application-prod.yml:
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}Farq:
local → oddiy lokal config bo‘lishi mumkin
dev/prod → secretlar env orqali22. Product API uchun config misol
application.yml:
spring:
application:
name: shop-api
profiles:
active: local
app:
pagination:
default-page-size: 20
max-page-size: 100application-local.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_db
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: validate
show-sql: true
flyway:
enabled: true
locations: classpath:db/migrationapplication-prod.yml:
server:
port: ${SERVER_PORT:8080}
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
flyway:
enabled: true
locations: classpath:db/migration
app:
pagination:
default-page-size: ${DEFAULT_PAGE_SIZE:20}
max-page-size: ${MAX_PAGE_SIZE:100}23. Pagination config’ni classga chiqarish
application.yml:
app:
pagination:
default-page-size: 20
max-page-size: 100Properties class:
import jakarta.validation.constraints.Min;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@Validated
@ConfigurationProperties(prefix = "app.pagination")
public record PaginationProperties(
@Min(1)
int defaultPageSize,
@Min(1)
int maxPageSize
) {
}Config registration:
@Configuration
@EnableConfigurationProperties(PaginationProperties.class)
public class AppPropertiesConfig {
}Service’da ishlatish:
@Service
public class ProductService {
private final PaginationProperties paginationProperties;
public ProductService(PaginationProperties paginationProperties) {
this.paginationProperties = paginationProperties;
}
public Page<ProductResponse> getAll(Integer page, Integer size) {
int finalPage = page == null ? 0 : page;
int finalSize = size == null
? paginationProperties.defaultPageSize()
: Math.min(size, paginationProperties.maxPageSize());
Pageable pageable = PageRequest.of(finalPage, finalSize);
// repository call
return Page.empty(pageable);
}
}24. Config priority: qaysi biri ustun?
Spring Boot’da config manbalari ko‘p bo‘lishi mumkin:
application.yml
application-prod.yml
environment variables
command line argumentsAmaliy jihatdan eslab qolish:
Command line argument ko‘pincha yuqoriroq priority
Environment variable ham file configni override qila oladi
Profile-specific file umumiy application.yml ustidan yozadiMasalan:
application.yml:
server:
port: 8080Run command:
java -jar app.jar --server.port=9090Natija:
server.port = 909025. Docker bilan profile ishlatish
Docker run:
docker run \
-e SPRING_PROFILES_ACTIVE=prod \
-e DB_URL=jdbc:postgresql://db:5432/shop_db \
-e DB_USERNAME=shop_user \
-e DB_PASSWORD=secret \
-p 8080:8080 \
shop-api:latestDocker Compose:
services:
app:
image: shop-api:latest
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: prod
DB_URL: jdbc:postgresql://db:5432/shop_db
DB_USERNAME: shop_user
DB_PASSWORD: secret26. Test profile
Testlar uchun alohida profile foydali.
application-test.yml:
spring:
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
jpa:
hibernate:
ddl-auto: create-dropTest class:
@SpringBootTest
@ActiveProfiles("test")
class ProductServiceTest {
}Bu test paytida application-test.yml ishlatadi.
27. @ActiveProfiles
@ActiveProfiles testlarda profile tanlash uchun ishlatiladi.
@SpringBootTest
@ActiveProfiles("test")
class ProductControllerTest {
}Bu test environment’ni production configdan ajratadi.
Muhim:
Test hech qachon production databasega ulanmasligi kerak.28. Configuration class nima?
Ba’zan beanlarni alohida config classda e’lon qilamiz.
@Configuration
public class AppConfig {
@Bean
public Clock clock() {
return Clock.systemUTC();
}
}Endi Clock kerak bo‘lgan joyda inject qilinadi:
@Service
public class TimeService {
private final Clock clock;
public TimeService(Clock clock) {
this.clock = clock;
}
}Profile bilan:
@Configuration
@Profile("test")
public class TestConfig {
@Bean
public Clock fixedClock() {
return Clock.fixed(
Instant.parse("2026-01-01T00:00:00Z"),
ZoneOffset.UTC
);
}
}29. Ko‘p uchraydigan xatolar
Xato 1: Production secretni Gitga yozish
Yomon:
spring:
datasource:
password: real-prod-passwordTo‘g‘ri:
spring:
datasource:
password: ${DB_PASSWORD}Xato 2: prod profile’da show-sql: true
Yomon:
spring:
jpa:
show-sql: trueProduction’da keraksiz SQL loglar chiqadi.
Xato 3: ddl-auto=updateni prod’da qoldirish
Yomon:
spring:
jpa:
hibernate:
ddl-auto: updateYaxshi:
spring:
jpa:
hibernate:
ddl-auto: validateXato 4: Hamma configni @Value bilan tarqatib yuborish
Yomon:
@Value("${app.jwt.secret}")
private String secret;
@Value("${app.jwt.expiration-minutes}")
private Long expiration;Katta config uchun yaxshiroq:
@ConfigurationProperties(prefix = "app.jwt")
public record JwtProperties(...) {}Xato 5: Active profile’ni kodga qattiq bog‘lash
Yomon:
spring:
profiles:
active: prodBuni production jar ichida qoldirish xavfli. Serverda environment variable orqali berish yaxshiroq:
SPRING_PROFILES_ACTIVE=prod30. Java developer uchun qisqa qoida
application.yml → umumiy config
application-local.yml → lokal muhit
application-dev.yml → dev server
application-prod.yml → production
spring.profiles.active → qaysi profile ishlashini tanlaydi
@Profile → bean faqat ma’lum profile’da yaratiladi
@Value → oddiy bitta qiymat uchun
@ConfigurationProperties → katta/type-safe config uchun
Environment variables → secret va server-specific config uchun31. Amaliy vazifa
Oldingi Product CRUD API loyihasiga profile va config qo‘shing.
Fayllar
src/main/resources/application.yml
src/main/resources/application-local.yml
src/main/resources/application-prod.ymlapplication.yml
spring:
application:
name: shop-api
profiles:
active: local
app:
pagination:
default-page-size: 20
max-page-size: 100
jwt:
secret: ${JWT_SECRET:local-secret}
expiration-minutes: ${JWT_EXPIRATION_MINUTES:60}
issuer: shop-apiapplication-local.yml
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop_db
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: validate
show-sql: true
flyway:
enabled: trueapplication-prod.yml
server:
port: ${SERVER_PORT:8080}
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
flyway:
enabled: trueProperties classlar
PaginationProperties
JwtProperties
AppPropertiesConfigTalablar
JWT secret @ConfigurationProperties orqali o‘qilsin
Pagination max size configdan olinsin
Prod secretlar environment variable orqali berilsin
Testlarda @ActiveProfiles("test") ishlatilsinXulosa
Configuration & profiles real Spring Boot application’ni professional boshqarish uchun kerak.
Eng muhim fikr:
Kod o‘zgarmaydi.
Config muhitga qarab o‘zgaradi.Java developer quyidagilarni bilishi kerak:
application.yml
application-{profile}.yml
spring.profiles.active
@Profile
@Value
@ConfigurationProperties
@EnableConfigurationProperties
environment variables
default values: ${VAR:default}
local/dev/prod config ajratish
secretlarni Gitga yozmaslik