Eğitim Portalı/Spring Boot/Spring Boot Nedir ve İlk Uygulama
Spring Boot03-spring-boot/00-spring-boot-nedir-ve-ilk-uygulama

Spring Boot Nedir ve İlk Uygulama

Spring Framework'ün gücünü gördük; ama saf Spring'le bir web uygulaması kurmak hâlâ epey yapılandırma (sunucu kurulumu, bağımlılık uyumu, XML/Java config) gerektirir. Spring Boot, bu kurulum yükünü neredeyse sıfıra in…

Spring Boot Nedir ve İlk Uygulama

Spring Framework'ün gücünü gördük; ama saf Spring'le bir web uygulaması kurmak hâlâ epey yapılandırma (sunucu kurulumu, bağımlılık uyumu, XML/Java config) gerektirir. Spring Boot, bu kurulum yükünü neredeyse sıfıra indirir: "convention over configuration" (yapılandırma yerine makul varsayımlar) felsefesiyle, birkaç satırda çalışan, üretime hazır bir uygulama elde edersin. Bu bölümde Boot'un ne olduğunu ve ilk web uygulamamızı kuruyoruz.

Spring vs Spring Boot

Spring Framework, IoC/DI, web, veri, güvenlik gibi yapı taşlarını sunar — ama bunları birleştirmek, sürümlerini uyumlamak ve bir sunucu kurmak sana kalır. Spring Boot, Spring'in üzerine kurulu bir katmandır ve şunları getirir:

  • Otomatik yapılandırma (auto-configuration): Classpath'e bakıp makul varsayılanları kurar (web varsa gömülü Tomcat + Jackson, H2 varsa bir DataSource...).
  • Starter bağımlılıklar: spring-boot-starter-web gibi tek bir bağımlılık, uyumlu kütüphane setini birlikte getirir.
  • Gömülü sunucu: Ayrı bir Tomcat kurmana gerek yok; uygulama kendi sunucusunu içinde taşır (java -jar ile çalışır).
  • Üretim özellikleri: Actuator (sağlık/metrik), dışsal yapılandırma, profiller.

Kısaca: Spring "ne" sağlar, Spring Boot onu "hızlı ve hazır" hâle getirir.

İlk uygulama

Bir Spring Boot uygulamasının kalbi @SpringBootApplication ile işaretli bir sınıf ve bir main metodudur:

@SpringBootApplication
public class Ornek1 {
    public static void main(String[] args) {
        SpringApplication.run(Ornek1.class, args); // context + gömülü Tomcat
    }
    @RestController
    static class SelamController {
        @GetMapping("/selam") String selam() { return "Merhaba Spring Boot!"; }
    }
}

SpringApplication.run(...) tek satırda: Spring context'i kurar, otomatik yapılandırmayı çalıştırır ve gömülü Tomcat'i başlatır. @RestController içindeki metotların dönüş değeri doğrudan HTTP yanıtı olur. Örnek 1 (./Ornek1.java) bu uygulamayı kurar ve açılışta kendi /selam endpoint'ini RestClient ile çağırıp sonucu yazar.

Bu portalda Boot örnekleri gömülü Tomcat ile gerçekten başlatılır, kendilerini çağırıp çıktı üretir, ardından sunucu açık kaldığı için otomatik durdurulur. Yani gördüğün çıktı, canlı çalışan bir web uygulamasından gelir.

@SpringBootApplication ne yapar?

Bu tek anotasyon, aslında üçünü birleştirir:

  • @Configuration — sınıf bir yapılandırma kaynağıdır.
  • @EnableAutoConfiguration — Boot'un otomatik yapılandırma sihrini açar.
  • @ComponentScan — bu sınıfın paketini ve alt paketlerini tarar, bean'leri bulur.

Örnek 2 (./Ornek2.java) container'da otomatik oluşturulan bean sayısını yazdırır (çoğu auto-configuration ile gelir) ve dış yapılandırma değerlerini @Value ile enjekte eder.

Dış yapılandırma: application.properties / @Value

Spring Boot, ayarları koddan ayırır. Değerler application.properties veya application.yml dosyasından, ortam değişkenlerinden veya komut satırı argümanlarından gelir; koda @Value ile enjekte edilir:

@Value("${uygulama.ad}")     String ad;
@Value("${uygulama.dil:tr}") String dil; // yoksa varsayılan "tr"
# application.yml örneği
uygulama:
  ad: Eğitim Portalı
server:
  port: 8080

İlk REST ve JSON

Spring Boot, nesneleri elle JSON'a çevirmeni gerektirmez; bir nesne (ör. bir record) döndürürsün, Boot (Jackson ile) onu otomatik JSON'a serileştirir:

@GetMapping("/urunler") List<Urun> hepsi() { return urunler; } // -> JSON dizisi
@GetMapping("/urunler/{id}") Urun bul(@PathVariable int id) { ... }
@GetMapping("/ara") List<Urun> ara(@RequestParam String kelime) { ... }

Örnek 3 (./Ornek3.java) @PathVariable, @RequestParam ve nesne→JSON dönüşümünü canlı endpoint'lerle gösterir. Bir sonraki bölümde REST'i (POST/PUT/DELETE, durum kodları, ResponseEntity) derinleştireceğiz.

Proje yapısı ve Initializr

Gerçek bir Boot projesi genelde Spring Initializr (start.spring.io) ile oluşturulur: gerekli starter'ları seçersin, hazır bir Maven/Gradle projesi iner. Tipik yapı:

src/main/java/...        # kod (Application sınıfı, controller/service/repository)
src/main/resources/
  application.yml        # yapılandırma
  static/, templates/    # statik içerik / şablonlar
src/test/java/...        # testler

Özet

Spring Boot'un Spring üzerine kurduğu kolaylıkları (auto-configuration, starter'lar, gömülü sunucu) öğrendik; @SpringBootApplication ile ilk web uygulamamızı kurduk, @Value ile dış yapılandırmayı okuduk ve nesne→JSON dönüşümüyle ilk REST endpoint'lerimizi yazdık. Sırada, REST API geliştirmeyi tüm detaylarıyla ele alıyoruz: HTTP metotları, ResponseEntity ve durum kodları.

Kod Örnekleri(3)

Ornek1

ortam gerekir
Ornek1.java
1// Ornek1: İlk Spring Boot uygulaması — birkaç satırla çalışan bir web sunucusu.
2// @SpringBootApplication + bir @RestController; uygulama açılınca KENDİ endpoint'ini çağırır.
3// Çalıştırma: portal derleyip gömülü Tomcat ile başlatır, çıktıyı alıp durdurur.
4package com.egitim.springboot.giris;
5
6import org.springframework.boot.CommandLineRunner;
7import org.springframework.boot.SpringApplication;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
10import org.springframework.context.annotation.Bean;
11import org.springframework.web.bind.annotation.GetMapping;
12import org.springframework.web.bind.annotation.RestController;
13import org.springframework.web.client.RestClient;
14
15// @SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan
16// (Bu basit örnekte veritabanı gerekmediği için DataSource otomatik yapılandırmasını kapatıyoruz.)
17@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
18public class Ornek1 {
19
20    public static void main(String[] args) {
21        // Tek satır: Spring Boot context'i kurar, gömülü Tomcat'i 8080'de başlatır.
22        SpringApplication.run(Ornek1.class, args);
23    }
24
25    // @RestController: metotların dönüş değeri doğrudan HTTP yanıt gövdesi olur.
26    @RestController
27    static class SelamController {
28        @GetMapping("/selam")
29        String selam() {
30            return "Merhaba Spring Boot! (gömülü Tomcat, sıfır XML yapılandırma)";
31        }
32
33        @GetMapping("/saat")
34        String saat() {
35            return "Sunucu çalışıyor.";
36        }
37    }
38
39    // Uygulama ayağa kalkınca kendi endpoint'ini çağırıp sonucu yazdırır.
40    @Bean
41    CommandLineRunner selfTest() {
42        return args -> {
43            RestClient client = RestClient.create("http://localhost:8080");
44            System.out.println("\n================ SELF-TEST ================");
45            System.out.println("GET /selam -> " + client.get().uri("/selam").retrieve().body(String.class));
46            System.out.println("GET /saat  -> " + client.get().uri("/saat").retrieve().body(String.class));
47            System.out.println("===========================================");
48            System.out.println("Sunucu 8080'de açık. (curl http://localhost:8080/selam ile de denenebilir.)");
49        };
50    }
51}
canlı çalıştırma için ortam gerekir

Bu örnek Spring / Spring Boot (Gradle) ortamı gerektirir; tek dosya olarak java Ornek1.java ile çalışmaz. Orijinal portal bunu gömülü Tomcat / Spring context ile koşuyordu. Beklenen davranış yukarıdaki anlatım ve kodda açıklanmıştır.

Ornek2

ortam gerekir
Ornek2.java
1// Ornek2: @SpringBootApplication ne yapar + application properties / @Value.
2// Otomatik yapılandırma (auto-configuration) ve dış yapılandırma değerlerinin enjeksiyonu.
3// Çalıştırma: portal derleyip gömülü Tomcat ile başlatır.
4package com.egitim.springboot.giris;
5
6import org.springframework.beans.factory.annotation.Value;
7import org.springframework.boot.CommandLineRunner;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
10import org.springframework.boot.builder.SpringApplicationBuilder;
11import org.springframework.context.ApplicationContext;
12import org.springframework.context.annotation.Bean;
13import org.springframework.web.bind.annotation.GetMapping;
14import org.springframework.web.bind.annotation.RestController;
15import org.springframework.web.client.RestClient;
16
17@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
18public class Ornek2 {
19
20    public static void main(String[] args) {
21        // Properties normalde application.properties/yml'den gelir; burada gösterim için
22        // SpringApplicationBuilder ile programatik veriyoruz.
23        new SpringApplicationBuilder(Ornek2.class)
24                .properties("uygulama.ad=Eğitim Portalı", "uygulama.surum=2.0")
25                .run(args);
26    }
27
28    @RestController
29    static class BilgiController {
30        // @Value ile dış yapılandırma değerleri enjekte edilir (:varsayilan ile yedek).
31        @Value("${uygulama.ad}")        String ad;
32        @Value("${uygulama.surum}")     String surum;
33        @Value("${uygulama.dil:tr}")    String dil; // tanımlı değil -> varsayılan
34
35        @GetMapping("/bilgi")
36        String bilgi() {
37            return "ad=" + ad + ", sürüm=" + surum + ", dil=" + dil;
38        }
39    }
40
41    @Bean
42    CommandLineRunner selfTest(ApplicationContext ctx) {
43        return args -> {
44            System.out.println("\n================ AUTO-CONFIG + PROPERTIES ================");
45            System.out.println("@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan");
46            // Auto-configuration sayesinde otomatik oluşturulan bean sayısı (Tomcat, Jackson, ...).
47            System.out.println("Container'daki bean sayısı: " + ctx.getBeanDefinitionCount()
48                    + " (çoğu otomatik yapılandırıldı)");
49
50            RestClient client = RestClient.create("http://localhost:8080");
51            System.out.println("GET /bilgi -> " + client.get().uri("/bilgi").retrieve().body(String.class));
52            System.out.println("==========================================================");
53        };
54    }
55}
canlı çalıştırma için ortam gerekir

Bu örnek Spring / Spring Boot (Gradle) ortamı gerektirir; tek dosya olarak java Ornek2.java ile çalışmaz. Orijinal portal bunu gömülü Tomcat / Spring context ile koşuyordu. Beklenen davranış yukarıdaki anlatım ve kodda açıklanmıştır.

Ornek3

ortam gerekir
Ornek3.java
1// Ornek3: İlk REST + JSON — nesne döndür, Spring Boot otomatik JSON'a çevirsin.
2// @PathVariable, @RequestParam ve nesne->JSON (Jackson) dönüşümü.
3// Çalıştırma: portal derleyip gömülü Tomcat ile başlatır.
4package com.egitim.springboot.giris;
5
6import org.springframework.boot.CommandLineRunner;
7import org.springframework.boot.SpringApplication;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
10import org.springframework.context.annotation.Bean;
11import org.springframework.web.bind.annotation.GetMapping;
12import org.springframework.web.bind.annotation.PathVariable;
13import org.springframework.web.bind.annotation.RequestParam;
14import org.springframework.web.bind.annotation.RestController;
15import org.springframework.web.client.RestClient;
16
17import java.util.List;
18
19@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
20public class Ornek3 {
21
22    public static void main(String[] args) {
23        SpringApplication.run(Ornek3.class, args);
24    }
25
26    // Domain nesnesi: dönüş değeri otomatik olarak JSON'a serileştirilir (Jackson).
27    record Urun(int id, String ad, double fiyat) {}
28
29    @RestController
30    static class UrunController {
31        private final List<Urun> urunler = List.of(
32                new Urun(1, "Klavye", 450), new Urun(2, "Mouse", 250), new Urun(3, "Monitör", 3200));
33
34        // GET /urunler -> tüm liste (JSON dizisi)
35        @GetMapping("/urunler")
36        List<Urun> hepsi() { return urunler; }
37
38        // GET /urunler/{id} -> @PathVariable ile yol değişkeni
39        @GetMapping("/urunler/{id}")
40        Urun bul(@PathVariable int id) {
41            return urunler.stream().filter(u -> u.id() == id).findFirst().orElse(null);
42        }
43
44        // GET /ara?kelime=... -> @RequestParam ile sorgu parametresi
45        @GetMapping("/ara")
46        List<Urun> ara(@RequestParam String kelime) {
47            return urunler.stream().filter(u -> u.ad().toLowerCase().contains(kelime.toLowerCase())).toList();
48        }
49    }
50
51    @Bean
52    CommandLineRunner selfTest() {
53        return args -> {
54            RestClient c = RestClient.create("http://localhost:8080");
55            System.out.println("\n================ REST + JSON ================");
56            System.out.println("GET /urunler      -> " + c.get().uri("/urunler").retrieve().body(String.class));
57            System.out.println("GET /urunler/2    -> " + c.get().uri("/urunler/2").retrieve().body(String.class));
58            System.out.println("GET /ara?kelime=mo-> " + c.get().uri("/ara?kelime=mo").retrieve().body(String.class));
59            System.out.println("=============================================");
60            System.out.println("Dikkat: nesneleri elle JSON'a çevirmedik; Spring Boot (Jackson) otomatik yaptı.");
61        };
62    }
63}
canlı çalıştırma için ortam gerekir

Bu örnek Spring / Spring Boot (Gradle) ortamı gerektirir; tek dosya olarak java Ornek3.java ile çalışmaz. Orijinal portal bunu gömülü Tomcat / Spring context ile koşuyordu. Beklenen davranış yukarıdaki anlatım ve kodda açıklanmıştır.