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-webgibi 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 -jarile ç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 gerekir1// 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}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 gerekir1// 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}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 gerekir1// 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}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.