Spring Boot Annotations (Anotasyonlara Genel Bakış)
Spring Boot, "yapılandırmayı koda gömme" felsefesini anotasyonlarla hayata geçirir. XML yapılandırma dosyaları yerine, sınıflarını ve metotlarını anotasyonlarla işaretlersin; Spring bunları okuyup bean'leri oluşturur,…
Spring Boot Annotations (Anotasyonlara Genel Bakış)
Spring Boot, "yapılandırmayı koda gömme" felsefesini anotasyonlarla hayata geçirir. XML yapılandırma dosyaları yerine, sınıflarını ve metotlarını anotasyonlarla işaretlersin; Spring bunları okuyup bean'leri oluşturur, bağlar ve davranışları uygular. Bu konu, en çok kullanılan Spring Boot anotasyonlarını gruplar halinde, çalışan bir örnekle ele alır. (İlgili konular: stereotip bileşenler topic 10, yapılandırma topic 14, Java anotasyon temelleri topic 81.)
Önyükleme (bootstrap)
@SpringBootApplication: Ana sınıf. Üç anotasyonu birleştirir:@SpringBootConfiguration(yapılandırma sınıfı),@EnableAutoConfiguration(otomatik yapılandırma — classpath'e göre),@ComponentScan(bileşen tarama — bu paketten aşağısı).
Bileşen (stereotype) anotasyonları
@Component ve özelleşmeleri — Spring bunları tarayıp bean yapar:
| Anotasyon | Katman |
|---|---|
@Component | Genel bean |
@Service | İş mantığı (topic 10) |
@Repository | Veri erişimi |
@RestController / @Controller | Web (topic 01) |
@Configuration + @Bean | Manuel bean tanımı |
Bağımlılık enjeksiyonu (DI)
- Constructor injection (önerilen): Spring, constructor parametrelerini otomatik enjekte eder
(tek constructor'da
@Autowiredbile gerekmez). @Autowired: Alan/setter enjeksiyonu (constructor tercih edilir).@Qualifier("ad"): Aynı tipten birden çok bean varsa hangisini istediğini belirt.@Primary: Aynı tipten çok bean varsa varsayılan olanı işaretle.
@Service @Primary class EpostaGonderici implements BildirimGonderici { ... } @Service("sms") class SmsGonderici implements BildirimGonderici { ... } @Component class Servis { Servis(BildirimGonderici varsayilan, // @Primary -> Eposta @Qualifier("sms") BildirimGonderici sms) { ... } // -> Sms }
Örnek 1 (./Ornek1.java) @Primary/@Qualifier ile seçimi, constructor injection'ı, @Value ve
@Bean fabrika metodunu çalışır biçimde gösterir.
Web anotasyonları (topic 01)
@RequestMapping, @GetMapping/@PostMapping/@PutMapping/@DeleteMapping, @RequestBody,
@PathVariable, @RequestParam, @RequestHeader, @ResponseStatus, @RestControllerAdvice,
@CrossOrigin.
Yapılandırma ve koşullu wiring
@Value("${anahtar}"): Tekil yapılandırma değeri (topic 14).@ConfigurationProperties: Tipli/gruplu yapılandırma (topic 14).@Profile("prod"): Bean'i yalnızca belirli profilde yükle.@Conditional...(@ConditionalOnProperty,@ConditionalOnMissingBean...): Otomatik yapılandırmanın kalbi — koşula göre bean oluştur (Spring Boot'un "akıllı varsayılanları" bunlarla çalışır).
Davranışsal anotasyonlar
@Transactional (transaction — topic 02-spring/07), @Cacheable/@Async/@Scheduled (topic 05),
@Valid/@Validated (doğrulama — topic 03), @PreAuthorize/@Secured (yetki — topic 04).
Özet
Spring Boot anotasyonlarını gruplar halinde öğrendik: önyükleme (@SpringBootApplication ve üç
bileşeni), stereotip bileşenler, DI (@Autowired/@Qualifier/@Primary/constructor injection —
Örnek 1), web, yapılandırma/koşullu (@Value/@ConfigurationProperties/@Conditional) ve
davranışsal (@Transactional/@Cacheable/@Async) anotasyonlar. Anotasyonlar Spring Boot'un
"sihrinin" arkasındaki mekanizmadır. Sırada, gömülü sunucu yapılandırması: Tomcat port ve sunucu
ayarları.
▶ Kod Örnekleri(1)
Ornek1
ortam gerekir1// Ornek1: Spring Boot anotasyonları — bileşen tarama, DI, @Primary/@Qualifier, @Bean, @Value.
2// Çalıştırma: portal gömülü Tomcat ile başlatır, self-test çıktısını alır.
3package com.egitim.springboot.annotations;
4
5import org.springframework.beans.factory.annotation.Qualifier;
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.annotation.Bean;
12import org.springframework.context.annotation.Primary;
13import org.springframework.stereotype.Component;
14import org.springframework.stereotype.Service;
15
16@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
17public class Ornek1 {
18
19 public static void main(String[] args) {
20 new SpringApplicationBuilder(Ornek1.class).properties("uygulama.surum=1.0").run(args);
21 }
22
23 interface BildirimGonderici { String gonder(String mesaj); }
24
25 // @Service + @Primary: aynı tipten birden çok bean varsa VARSAYILAN bu seçilir.
26 @Service @Primary
27 static class EpostaGonderici implements BildirimGonderici {
28 public String gonder(String m) { return "[E-POSTA] " + m; }
29 }
30
31 // @Service + isim: @Qualifier ile özellikle bu istenebilir.
32 @Service("sms")
33 static class SmsGonderici implements BildirimGonderici {
34 public String gonder(String m) { return "[SMS] " + m; }
35 }
36
37 // @Component: genel bir bean. Bağımlılıkları CONSTRUCTOR ile enjekte edilir (önerilen).
38 @Component
39 static class BildirimServisi {
40 private final BildirimGonderici varsayilan; // @Primary olan (Eposta) gelir
41 private final BildirimGonderici sms; // @Qualifier ile SMS gelir
42 @Value("${uygulama.surum}") String surum; // yapılandırmadan değer
43
44 BildirimServisi(BildirimGonderici varsayilan, @Qualifier("sms") BildirimGonderici sms) {
45 this.varsayilan = varsayilan;
46 this.sms = sms;
47 }
48 String duyur(String m) { return varsayilan.gonder(m) + " / " + sms.gonder(m) + " (v" + surum + ")"; }
49 }
50
51 // @Bean: bir nesneyi (kendi sınıfın olmasa bile) bean olarak kaydet (fabrika metodu).
52 @Bean
53 java.time.Clock saat() { return java.time.Clock.systemDefaultZone(); }
54
55 @Bean
56 CommandLineRunner selfTest(BildirimServisi servis, java.time.Clock saat) {
57 return args -> {
58 System.out.println("\n========= ANNOTATIONS SELF-TEST =========");
59 System.out.println("Enjekte edilen servis: " + servis.duyur("Sipariş hazır"));
60 System.out.println(" -> @Primary 'Eposta'yı, @Qualifier(\"sms\") 'Sms'i seçti.");
61 System.out.println("@Bean ile kaydedilen Clock var mı? " + (saat != null));
62 System.out.println("=========================================");
63 };
64 }
65}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.