Tutorial

264 posts in this section

Spring Boot Actuator: Health, Metrics, and Management Endpoints

A running application is not enough — you need to know if it’s healthy, how it’s performing, and what it’s doing. Spring Boot Actuator exposes that information through HTTP endpoints and metrics. Setup <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> By default, only /actuator/health and /actuator/info are exposed over HTTP. Everything else is available via JMX. Enable what you need: management: endpoints: web: exposure: include: health,info,metrics,prometheus,conditions,beans,env,loggers,threaddump,heapdump base-path: /actuator endpoint: health: show-details: when-authorized # or 'always' (dev), 'never' (public) show-components: when-authorized metrics: enabled: true server: port: 8081 # expose actuator on a separate port (not public-facing) Health Endpoint GET /actuator/health — used by Kubernetes liveness/readiness probes and load balancers:

Continue reading »

Spring Boot Integration: Zero-Config Setup and Full Properties Reference

Running Liquibase from the CLI is fine for learning and for standalone scripts. In a real Spring Boot application, you want migrations to run automatically at startup — before the application code touches the database. Spring Boot’s Liquibase auto-configuration handles this with zero boilerplate: add the dependency, point to your changelog, and migrations run before the application context is ready. This article covers the complete integration: Maven/Gradle setup, how auto-run works and why, the full spring.

Continue reading »

Spring Boot on Kubernetes

Kubernetes is the standard platform for running containerized microservices. Spring Boot integrates naturally with Kubernetes — Actuator probes map directly to Kubernetes probes, and Spring configuration maps to ConfigMaps and Secrets. Core Kubernetes Resources Deployment # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: order-service labels: app: order-service spec: replicas: 3 selector: matchLabels: app: order-service template: metadata: labels: app: order-service version: "1.2.3" spec: containers: - name: order-service image: devopsmonk/order-service:1.2.3 ports: - containerPort: 8080 name: http - containerPort: 8081 name: management # Resource limits — always set these resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "1000m" # Environment from ConfigMap and Secret envFrom: - configMapRef: name: order-service-config - secretRef: name: order-service-secrets # Individual env vars env: - name: SPRING_PROFILES_ACTIVE value: prod - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.

Continue reading »

Spring Boot Project Structure Explained

A Spring Boot project looks simple on the surface but has a specific structure with specific conventions. Understanding it upfront saves hours of confusion later. The Standard Layout order-service/ ├── pom.xml ├── mvnw # Maven Wrapper script (Unix) ├── mvnw.cmd # Maven Wrapper script (Windows) ├── .mvn/ │ └── wrapper/ │ └── maven-wrapper.properties └── src/ ├── main/ │ ├── java/ │ │ └── com/devopsmonk/orderservice/ │ │ └── OrderServiceApplication.java │ └── resources/ │ ├── application.

Continue reading »

Spring Data with PostgreSQL

PostgreSQL offers powerful features beyond basic SQL — JSONB, arrays, full-text search, advisory locks. This article shows how to use them from Spring Boot and how to tune HikariCP for production. Project Setup <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> spring: datasource: url: jdbc:postgresql://localhost:5432/orderdb username: app password: ${DB_PASSWORD} driver-class-name: org.postgresql.Driver jpa: database-platform: org.hibernate.dialect.PostgreSQLDialect hibernate: ddl-auto: validate HikariCP — Connection Pool Tuning Spring Boot uses HikariCP by default — the fastest JDBC connection pool.

Continue reading »

Spring IoC and Dependency Injection

Every Spring Boot application is built on one idea: the framework creates and wires your objects, not you. This article explains how that works and how to use it effectively. Inversion of Control In traditional Java, you create objects yourself: // You control the dependencies public class OrderService { private final OrderRepository repository = new JpaOrderRepository(); private final EmailService email = new SmtpEmailService("smtp.gmail.com"); } Problems: OrderService is tightly coupled to specific implementations You can’t swap JpaOrderRepository for a mock in tests without editing OrderService If SmtpEmailService needs its own dependencies, you must construct those too Inversion of Control (IoC) flips this: instead of creating your dependencies, you declare what you need and let a container provide them.

Continue reading »

Spring Security Fundamentals: Filter Chain, Authentication, and Authorization

Spring Security is powerful but famously hard to understand. This article demystifies the core: the filter chain, how requests are processed, and how authentication and authorization work before writing a line of security config. Setup <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> The moment you add this dependency, Spring Boot’s auto-configuration secures all endpoints with HTTP Basic authentication. A random password is printed at startup. This is the starting point — you’ll replace the defaults.

Continue reading »

Stored Procedures, Views, and Triggers in MySQL

Tables and columns are straightforward in Liquibase — one change type per operation, automatic rollback, clean history. Stored procedures, views, and triggers are different. They contain body SQL that uses semicolons internally, which conflicts with Liquibase’s default statement splitting. They are replaced rather than altered. And unlike tables, modifying them frequently over time is expected. This article covers the mechanics and patterns that make stored objects manageable in Liquibase. The Core Problem: Delimiter Conflicts A stored procedure body contains semicolons to terminate each statement inside it:

Continue reading »

Tasklets: Running Non-Chunk Operations in Batch Jobs

Introduction Not every step in a batch job reads-processes-writes a stream of items. Sometimes you need to: Delete yesterday’s temp files before reading today’s data Truncate a staging table before loading new data Call a stored procedure to aggregate results Send an email or Slack notification after processing Execute a DDL statement to add an index These operations do not have items — they are single units of work. Spring Batch handles them with the Tasklet interface.

Continue reading »

Team Collaboration: Naming Conventions, Conflict Prevention, Git Workflow

A solo developer can treat Liquibase conventions as suggestions. A team of five cannot. When two developers both write “the next migration” on the same day, without a convention that prevents collision, you get duplicate IDs, merge conflicts on the master changelog, or — worst case — two changesets that silently overwrite each other in DATABASECHANGELOG. This article is the operating agreement for teams using Liquibase: what conventions to establish, how to structure the git workflow, what the PR review checklist looks like, and what to do when conflicts happen despite the conventions.

Continue reading »