Başlangıç / Kurulum & Tanıma / Modül 00 — Spring Boot & MiniBank'a Giriş
Başlangıç Modül 00 Giriş & Kurulum Kod yazma yok

Spring Boot & MiniBank'a Giriş

Teknik detaya girmeden önce kısa bir oryantasyon: bu eğitimde ne inşa edeceğiz, nasıl çalışacağız, ortam nasıl kurulacak? Sonunda da elimizdeki MiniBank iskeletini tanıyacağız. Bu modülde kod yazmıyoruz; ortamı kuruyoruz ve haritayı çıkarıyoruz.

Süre
25 dk
Format
Kurulum + Tanıma
Branch
lab-00-base
Sonraki
Modül 01

Mini sözlük: Aynı dili konuşalım

Eğitim boyunca sık geçecek birkaç kelimeyi en baştan netleştirelim. Bu modülde derinleşmiyoruz; sadece kelimelerin ne anlama geldiğini oturtuyoruz.

SB

Spring Boot

Spring uygulamasını hızlı ve standart şekilde ayağa kaldırmamızı sağlayan framework'tür. Tekrar eden altyapı kararlarının çoğunu bizim yerimize verir.

MB

MiniBank

Eğitim boyunca adım adım geliştireceğimiz örnek bankacılık uygulamasıdır. Her modül bu tek ürünün üstüne yeni bir katman ekler.

LD

Lab Dashboard

MiniBank'in localhost:8080'de açılan kontrol panelidir. Her case'in görev listesi, doğrulama komutları ve referans kodu buradadır.

BR

Branch / Checkpoint

Her case'in bir start ve bir complete branch'i vardır. Bir case'in complete'i, bir sonrakinin start'ıdır; böylece herkes aynı noktadan devam eder.

JDK

JDK 17

Projeyi derlemek ve çalıştırmak için gereken Java sürümüdür. MiniBank Java 17 ile yazılmıştır.

MW

Maven Wrapper

./mvnw komutu, sistemde Maven kurulu olmasa bile projeyi doğru sürümle derleyip çalıştırır. Ayrı kurulum gerektirmez.

ES

Embedded Server

Spring Boot uygulaması harici bir sunucuya ihtiyaç duymadan kendi içindeki web server (Tomcat) ile ayağa kalkar.

ST

Starter

Bir özellik ailesini tek bağımlılıkla projeye ekleyen pakettir. Örneğin spring-boot-starter-web web katmanının ihtiyaçlarını birlikte getirir.

Bu eğitimde ne yapacağız?

Üç gün ve 11 modül boyunca tek bir ürün inşa edeceğiz: MiniBank. Sıfırdan başlayıp birikimli olarak production'a yakın bir olgunluğa ulaşacağız.

Bu eğitim bağımsız örneklerden oluşmaz. Her modül bir öncekinin bıraktığı yerin üstüne yeni bir yetenek ekler: önce çekirdek servis katmanı, sonra web katmanı, en sonunda güvenlik, veri ve gözlemlenebilirlik. Modül sonunda elinde ezberlenmiş parçalar değil, çalışan ve anlamlı bir banka API'si olur.

Gün 1 — Spring Core
  • 01 · Internal Mechanics
  • 02 · IoC & Bean Model
  • 03 · Spring AOP
Gün 2 — Web Layer
  • 04 · MVC Internals
  • 05 · REST API Properly
  • 06 · Exception Handling
  • 07 · Config & Profiles
Gün 3 — Production Basics
  • 08 · Spring Security
  • 09 · Data & Transactions
  • 10 · External API Calls
  • 11 · Observability
Birikimli yapı

Her case'in complete branch'i bir sonraki case'in start branch'idir. Bu yüzden geride kalsan bile bir sonraki modüle herkesle aynı noktadan girersin.

Spring Boot neden var?

Spring Boot'un temel vaadi sade: "Sen iş mantığına odaklan; uygulamayı ayağa kaldırmak için gereken standart parçaları ben hazırlayayım."

Bir web uygulaması yazmak sadece controller yazmak değildir. HTTP isteğini karşılayacak bir sunucu, isteği doğru metoda yönlendiren bir mekanizma, JSON dönüşümü, hata yönetimi, konfigürasyon okuma ve daha fazlası gerekir. Spring Boot bu tekrar eden parçaları yaygın ve güvenli varsayılanlarla hazırlar. Bu modülde sadece bu çerçeveyi tanıyoruz; nasıl çalıştığını Modül 01'de açacağız.

Convention over Configuration

Mantıklı varsayılanlar sayesinde her şeyi tek tek ayarlamak zorunda kalmazsın; sadece farklı olmasını istediğin yeri değiştirirsin.

Embedded Server

Uygulama kendi içindeki Tomcat ile ayağa kalkar; harici sunucu kurup deploy etme adımı ortadan kalkar.

Starter Bağımlılıkları

Bir özelliğin ihtiyaç duyduğu kütüphaneleri tek tek toplamak yerine tek bir starter ile getirirsin.

Bu modülde derinleşmiyoruz

Auto configuration, component scan ve bean lifecycle'ın nasıl çalıştığını burada açmıyoruz; o, Modül 01'in (Internal Mechanics) işidir. Şimdilik "Spring Boot bizim için neyi hallediyor" büyük resmini kurmak yeterli.

Nasıl çalışacağız?

Her modülde aynı akışı izleyeceğiz: önce portalda öğren, sonra dashboard'da case'i aç, eğitmenin erişime açtığı private lab repository'sini klonla, kendin yaz ve test ile doğrula.

01
Portalda öğren
Modül anlatımını (şu an okuduğun gibi) oku, kavramları otur.
02
Dashboard'da case aç
Lab Dashboard'da ilgili case'in görev listesini ve doğrulama adımlarını gör.
03
Lab repository'sini klonla
MiniBank-Lab-NN erişime açıldığında repository'yi klonla; çalışma branch'i main'dir.
04
Kendin yaz
Kodu sen yazarsın. Kopyala-yapıştır yok; takılırsan eğitmen paneli referanstır.
05
Test ile doğrula
Learning mode çalışırken uyarır; checkpoint mode yeşil olduğunda çekirdek case tamamlanmıştır.
Erişim kuralı

Yalnız eğitmenin açtığı lab repository'leri görünür. Referans çözüm katılımcı repository'sinde bulunmaz; eğitmen case kapanışında kararları ve kodu birlikte gösterir.

Geliştirme ortamı

Tek ihtiyacın JDK 17 ve projeyi klonlamak. Maven'ı ayrı kurmana gerek yok, çünkü proje kendi wrapper'ı (./mvnw) ile gelir.

Adım 1: JDK 17'yi doğrula

Terminali aç ve aşağıdaki komutu çalıştır. Çıktının ilk satırında 17 görmen gerekiyor. 11 veya 8 görüyorsan proje derlenmez; 21 gibi daha yeni bir sürüm de çalışır ama eğitimde herkesin aynı sürümde olması sorun ayıklamayı kolaylaştırır.

JDK kontrolü
$ java -version
openjdk version "17.0.11" 2024-04-16        # ilk satırda 17 olmalı
OpenJDK Runtime Environment Temurin-17...

"command not found" alıyorsan JDK kurulu değil demektir; aşağıdaki indirme linklerinden Temurin 17'yi kur ve terminali kapatıp yeniden aç.

Adım 2: Açılan ilk lab repository'sini klonla

MiniBank-Lab-00 repository'sini klonla
git clone https://github.com/definex-training/MiniBank-Lab-00.git
cd MiniBank-Lab-00
git branch   # * main görmelisin
Remote erişimi salt okunurdur

Katılımcıların GitHub repository'lerine push yetkisi yoktur. Kodunu yerel klonunda yazarsın; eğitmen sıradaki repository'yi panelden açana kadar sonraki lab görünmez.

Adım 3: Çalıştır ve doğrula

İlk çalıştırma
./mvnw spring-boot:run     # Windows'ta: mvnw.cmd spring-boot:run

İlk çalıştırma birkaç dakika sürebilir çünkü Maven önce bağımlılıkları indirir. Konsolda neler olacağını İlk Çalıştırma bölümünde satır satır göreceğiz. Uygulama kalktığında tarayıcıdan http://localhost:8080 adresini aç: Lab Dashboard seni karşılar. http://localhost:8080/api/status ise uygulamanın UP olduğunu söyleyen bir JSON döner. Port varsayılan olarak 8080'dir; base projede henüz özel bir application.yml yoktur, her şey Spring Boot'un varsayılanlarıyla çalışır.

Learning ve checkpoint testleri
# Çalışırken eksik scaffold build'i kesmez
./mvnw test -Dminibank.lab.mode=learning -Dtest=MiniBankLabCheckpointTests

# Case sonunda eksik veya yanlış davranış fail olur
./mvnw test -Dminibank.lab.mode=checkpoint -Dtest=MiniBankLabCheckpointTests

Araçlar & indirme linkleri

Eğitim için gereken ve işini kolaylaştıran araçlar. JDK 17, IntelliJ IDEA ve Git zorunlu; gerisi opsiyonel.

JDK

JDK 17 — Eclipse Temurin

Projeyi derleyip çalıştıran Java sürümü. Zorunlu.

İndir →
IDE

IntelliJ IDEA

Önerilen IDE. Community sürümü bu eğitim için yeterlidir. Zorunlu.

İndir →
GIT

Git

Repoyu klonlamak ve branch (checkpoint) geçişleri için. Zorunlu.

İndir →
MVN

Apache Maven · opsiyonel

Proje ./mvnw wrapper ile gelir; ayrı kurulum şart değil.

İndir →
API

Postman · opsiyonel

API isteklerini görsel denemek için (curl alternatifi).

İndir →
VSC

VS Code · alternatif

IntelliJ yerine kullanmak istersen, Java eklentileriyle.

İndir →
macOS / Linux kısayolu

JDK'yı paket yöneticisiyle de kurabilirsin: brew install temurin@17 (macOS Homebrew) veya SDKMAN ile sdk install java 17-tem.

Projeyi IntelliJ'de aç

Eğitim boyunca kodu IntelliJ IDEA içinde yazacağız. Projeyi ilk kez açarken şu adımları izle; toplamda 2-3 dakika sürer.

01
Open
IntelliJ'i aç, karşılama ekranında Open'a tıkla (File → Open).
02
Klasörü seç
Klonladığın MiniBank klasörünü seç. pom.xml'i değil, klasörün kendisini seçmek yeterli.
03
Trust Project
"Trust and Open" sorusuna onay ver. IntelliJ pom.xml'i görüp projeyi Maven projesi olarak tanır.
04
Import'u bekle
Sağ altta "Importing Maven projects" biter, bağımlılıklar iner. İlk seferde birkaç dakika sürebilir.
05
JDK'yı kontrol et
File → Project Structure → Project → SDK alanında 17 seçili olmalı. Değilse listeden 17'yi seç.

Her şey yolundaysa sol taraftaki proje ağacında src/main/java klasörü mavi (source root) görünür ve MiniBankApplication sınıfının yanında yeşil çalıştırma oku belirir. Bu oka tıklayarak uygulamayı IDE içinden de başlatabilirsin; terminaldeki ./mvnw spring-boot:run ile aynı işi yapar.

Neden hem terminal hem IDE?

IDE'den çalıştırmak gündelik geliştirmede pratiktir. Terminal komutunu da öğreniyoruz çünkü test doğrulamalarını (./mvnw test) ve CI ortamlarındaki davranışı IDE olmadan da çalıştırabilmen gerekir.

pom.xml: Projenin kimlik kartı

pom.xml, Maven'a "bu proje nedir, neye ihtiyaç duyar, nasıl derlenir" sorularının cevabını veren dosyadır. MiniBank'in gerçek pom.xml'inden en önemli kısımlara bakalım.

pom.xml — özet (lab-00-base'deki gerçek hali)
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.0</version>                <!-- Spring Boot sürümü -->
</parent>

<properties>
    <java.version>17</java.version>          <!-- JDK 17 şartı -->
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>       <!-- REST + Tomcat -->
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId> <!-- @NotBlank vb. -->
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>   <!-- /actuator/health -->
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>                                      <!-- JUnit + MockMvc -->
    </dependency>
</dependencies>

parent ne işe yarar?

spring-boot-starter-parent, yüzlerce kütüphanenin birbiriyle uyumlu sürümlerini tek yerden yönetir. Bu yüzden bağımlılıklarda tek tek <version> yazmıyoruz: sürümü parent belirler, çakışma derdi bizden kalkar.

starter ne getirir?

Tek satır starter-web eklemek; Spring MVC, JSON dönüşümü için Jackson ve embedded Tomcat'i birlikte getirir. Maven bu zinciri (transitive dependency) senin yerine çözer.

scope: test nedir?

starter-test yalnızca test derlenirken classpath'e girer; üretim jar'ına dahil olmaz. JUnit 5, AssertJ ve MockMvc bu paketle gelir.

enforcer ne yapar?

pom'daki maven-enforcer-plugin JDK 17 altı bir sürümle derlemeyi daha en başta, anlaşılır bir mesajla durdurur. Yanlış JDK ile dakikalarca hata aramazsın.

Maven Wrapper neden var?

./mvnw, projenin içinde sabitlenmiş Maven sürümünü indirir ve onu kullanır. Böylece "bende çalışıyor, sende niye çalışmıyor" sorununun bir kaynağı daha kapanır: herkes aynı Maven sürümüyle derler, kimsenin makinesine ayrıca Maven kurması gerekmez.

İlk çalıştırma: konsolda ne göreceksin?

./mvnw spring-boot:run dediğinde arka arkaya dört şey olur. Konsol çıktısını okuyabilmek, ileride sorun ayıklarken en çok işine yarayacak beceridir.

01
Bağımlılık inişi
İlk seferde Maven, pom.xml'deki starter'ları ve onların getirdiklerini indirir. "Downloading from central..." satırları bu aşamadır.
02
Derleme
Java kaynakları class dosyalarına derlenir. Hata varsa burada durur; satır numarasıyla birlikte yazar.
03
Spring banner + context
Spring Boot logosu basılır, ApplicationContext kurulur, bean'ler oluşturulur.
04
Tomcat hazır
"Tomcat started on port 8080" satırını gördüğünde uygulama istek almaya hazırdır.
Başarılı kalkışın imzası
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 ...
 :: Spring Boot ::                (v3.5.0)

INFO ... : Starting MiniBankApplication using Java 17
INFO ... : Tomcat initialized with port 8080 (http)
INFO ... : Root WebApplicationContext: initialization completed
INFO ... : Tomcat started on port 8080 (http) with context path '/'
INFO ... : Started MiniBankApplication in 1.8 seconds

Son iki satır kritik: "Tomcat started on port 8080" web sunucusunun dinlemede olduğunu, "Started MiniBankApplication" ise Spring context'inin sorunsuz kurulduğunu söyler. Bu iki satırı görmeden tarayıcıda adres açmaya çalışma; göremiyorsan Sorun Giderme bölümüne bak.

  • http://localhost:8080 açılıyor ve Lab Dashboard görünüyor.
  • http://localhost:8080/api/status şu JSON'u dönüyor: {"application":"MiniBank","status":"UP",...}
  • http://localhost:8080/actuator/health da {"status":"UP"} dönüyor (actuator starter'ın hediyesi).
  • Durdurmak için terminalde Ctrl+C.

Base project turu

lab-00-base bilinçli olarak neredeyse boş bir iskelettir: sadece uygulamanın ayağa kalkması ve dashboard'un servis edilmesi için gereken minimum vardır. Domain (hesap, müşteri, transfer…) henüz yoktur. Onları modül modül biz ekleyeceğiz.

lab-00-base — gerçek yapı
minibank
├── pom.xml                          # Spring Boot 3.5.0 · Java 17
├── mvnw / mvnw.cmd                  # Maven Wrapper
└── src
    ├── main
    │   ├── java/com/definex/minibank
    │   │   ├── MiniBankApplication.java   # @SpringBootApplication (giriş noktası)
    │   │   └── web
    │   │       └── HomeController.java     # GET /api/status
    │   └── resources
    │       └── static
    │           └── index.html             # Lab Dashboard
    └── test/java/com/definex/minibank
        ├── MiniBankApplicationTests.java      # context ayağa kalkıyor mu
        └── MiniBankHomeControllerTests.java   # status + dashboard

Başlangıçta NE VAR?

Uygulama giriş noktası (MiniBankApplication), tek bir HomeController (/api/status), statik Lab Dashboard ve iki temel test. pom.xml'de yalnızca web, validation ve actuator starter'ları.

Henüz NE YOK?

Domain paketleri yok: account, customer, transfer, security, persistence gibi paketler eğitim ilerledikçe ilgili modüllerde eklenecek.

src/main/java

Uygulamanın gerçek kodu burada yaşar. Üretim jar'ına giren her şey bu ağaçtan derlenir. Eğitim boyunca yazacağın sınıfların neredeyse tamamı buraya gidecek.

src/test/java

Testler burada yaşar; aynı paket yapısını aynalar ama üretim jar'ına girmez. Her case'in "bitti" tanımı bu ağaçtaki testlerin yeşil olmasıdır: ./mvnw test.

Giriş noktası: MiniBankApplication

Projedeki en küçük ama en önemli sınıf budur. Base projedeki gerçek hali şu:

src/main/java/com/definex/minibank/MiniBankApplication.java
package com.definex.minibank;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MiniBankApplication {

    public static void main(String[] args) {
        SpringApplication.run(MiniBankApplication.class, args);
    }
}

@SpringBootApplication tek bir annotation gibi görünür ama aslında üç annotation'ın kısaltmasıdır. Şimdilik isimlerini tanıman yeterli; her birinin mekanizmasını Modül 01'de tek tek açacağız:

@SpringBootConfiguration

"Bu sınıf bir konfigürasyon kaynağıdır" der. Uygulamanın tanım merkezi burasıdır.

@EnableAutoConfiguration

"Classpath'te ne görüyorsan ona göre kurulum yap" der. starter-web varsa Tomcat ve MVC bu sayede kendiliğinden kurulur.

@ComponentScan

"Bu paketten aşağı doğru tara, bulduğun bileşenleri yönet" der. Paket kök kuralının dayandığı yer burası.

İlk controller: HomeController

/api/status cevabını üreten sınıf da base projede hazır. İki annotation'a dikkat: @RestController sınıfı "HTTP isteklerine JSON cevap veren bileşen" yapar, @GetMapping ise metodu belirli bir URL'e bağlar. Dönen record tipini Spring otomatik olarak JSON'a çevirir; bu dönüşümün perde arkasını Modül 04'te göreceğiz.

src/main/java/com/definex/minibank/web/HomeController.java
@RestController
public class HomeController {

    @GetMapping("/api/status")
    public MiniBankStatus status() {
        return new MiniBankStatus(
                "MiniBank",
                "UP",
                "MiniBank API calisiyor.",
                List.of(
                        "GET / (Lab Dashboard)",
                        "GET /api/status",
                        "GET /actuator/health"));
    }

    public record MiniBankStatus(
            String application,
            String status,
            String message,
            List<String> links) {
    }
}

Paket kök kuralı

Tüm kod com.definex.minibank kök paketinin altında durur. MiniBankApplication bu kökte olduğu için, eklediğimiz her alt paket (account, customer …) otomatik olarak görülebilir konumda olur. Bunun neden böyle olduğunu Modül 01'de (component scanning) açacağız.

Lab Dashboard'da gör

Base project'i ve ilk çalıştırma adımlarını dashboard üzerinden de takip edebilirsin.

Lab Dashboard'da base project'i aç

Takıldıysan: en sık görülen 5 sorun

İlk kurulumda bir şeyler ters gittiyse büyük ihtimalle aşağıdakilerden biridir. Belirtiyi bul, çözümü uygula; hiçbiri tutmazsa eğitmene konsol çıktısının son 20 satırını göster.

1
"Port 8080 was already in use"

Başka bir uygulama (ya da unutulmuş eski bir MiniBank süreci) portu tutuyor. macOS/Linux'ta lsof -i :8080 ile süreci bul, kill <PID> ile kapat. Windows'ta netstat -ano | findstr 8080 sonra Görev Yöneticisi'nden sonlandır. En pratik yol: açık kalan eski terminalde Ctrl+C.

2
"release version 17 not supported" veya enforcer hatası

Terminalin eski bir JDK kullanıyor. java -version ile kontrol et. Birden çok JDK kuruluysa JAVA_HOME'u 17'ye işaret ettir; macOS'ta export JAVA_HOME=$(/usr/libexec/java_home -v 17) yeterli. IntelliJ içinde ayrıca Project Structure → SDK = 17 olmalı.

3
"./mvnw: Permission denied"

Wrapper dosyası çalıştırma izni kaybetmiş. chmod +x mvnw ile izni geri ver. Windows'ta bu sorun olmaz; orada mvnw.cmd kullanılır.

4
Bağımlılıklar inmiyor ("Could not transfer artifact")

Ağ ya da proxy sorunu. Kurumsal ağdaysan VPN/proxy ayarlarını kontrol et; gerekiyorsa ~/.m2/settings.xml dosyasına proxy tanımı ekle. Yarıda kesilen indirme bozuk dosya bırakabilir: rm -rf ~/.m2/repository/org/springframework deyip tekrar dene.

5
IntelliJ sınıfları kırmızı gösteriyor ama terminalde derleniyor

Maven import tamamlanmamış ya da cache karışmış. Sağdaki Maven panelinden "Reload All Maven Projects" butonuna bas. Düzelmezse File → Invalidate Caches → Invalidate and Restart.

Bu modülden akılda kalması gerekenler

1
Tek bir ürünü birikimli inşa ediyoruz.

11 modül, 3 gün; her case bir öncekinin üstüne ekler. Sonunda çalışan bir MiniBank API'si.

2
Çalışma ritmi sabit.

Portalda öğren → dashboard'da case aç → start branch → kendin yaz → test ile doğrula.

3
Checkpoint güvenliği var.

lab-NN-complete ile herkes aynı noktadan devam edebilir; kopyala-yapıştır değil, branch klonlanır.

4
Ortam minimum.

JDK 17 + ./mvnw spring-boot:run. Base proje localhost:8080'de ayağa kalkar.

5
Base bilinçli olarak boş.

Sadece MiniBankApplication + HomeController + dashboard var; domain paketlerini biz ekleyeceğiz.

6
Konsolu okumayı öğrendin.

"Tomcat started on port 8080" + "Started MiniBankApplication" çifti sağlıklı kalkışın imzasıdır; bu satırlar yoksa önce Sorun Giderme'ye bak.

Hazırsan başlayalım

Ortamın çalışıyor ve haritayı gördüysen, ilk teknik modüle geçebilirsin.

Modül 01 — Internal Mechanics'e Geç