Spring Bean Scopes Nedir? Singleton, Prototype, Request, Session | Tam Rehber

Spring Bean Scopes — Eksiksiz Rehber

Spring IoC container'ı bir bean oluşturduğunda, o bean'in kaç kez ve ne zaman yaratılacağını scope (kapsam) belirler. Doğru scope seçimi hem bellek kullanımını optimize eder hem de kötü sürprizlerin — thread-safety sorunları, oturum sızıntıları, WebSocket veri karışıklıkları — önüne geçer. Bu yazıda altı scope'u örnekler, karşılaştırmalar ve pratik kullanım önerileriyle ele alıyoruz.

Hızlı özet

  • Singleton — varsayılan; tüm uygulama için tek instance
  • Prototype — her istemde yeni instance; stateful nesneler için
  • Request / Session / Application / WebSocket — web uygulamalarına özel dört scope
  • Scope, @Scope anotasyonu ya da XML ile belirlenir

1) Bean Scope Nedir?

Spring IoC container, uygulamanın omurgasını oluşturan nesneleri — bean'leri — yönetir. Bir bean tanımlandığında container şu soruyu sorar: "Bu nesneyi kaç kez oluşturayım ve yaşam döngüsü ne olsun?" İşte bu soruyu scope yanıtlar.

Spring, iki temel (core) ve dört web scope'u olmak üzere toplam altı yerleşik scope sunar. Bunlara ek olarak özel scope'lar da tanımlanabilir.

"Her bean'in doğru scope'u vardır. Yanlış seçim performans sorunlarına ya da gizli hatalara kapı açar."

2) Singleton Scope

Spring'in varsayılan scope'udur. Container başladığında bean bir kez oluşturulur ve uygulama boyunca aynı instance paylaşılır.

@Service
// @Scope("singleton") — anotasyon olmadan da aynı davranış
public class UserService {
    // Tüm request'lerde paylaşılan tek instance
}

Ne zaman kullanılır?

State tutmayan (stateless) bileşenler için idealdir: @Service, @Repository, @Controller. Bellekte tek kopya olduğu için en verimli scope'tur.

Dikkat

Singleton bean'e mutable (değiştirilebilir) instance değişkeni eklenmemeli. Birden fazla thread aynı anda bu alanı değiştirebileceğinden thread-safety sorunu doğar.

3) Prototype Scope

Her bean isteminde (injection veya getBean() çağrısında) yeni bir instance oluşturulur. Container, bu instance'ın sonraki yaşam döngüsünü takip etmez; yönetim geliştiriciye kalır.

@Component
@Scope("prototype")
public class ShoppingCart {
    private List<Item> items = new ArrayList<>();
 
    public void addItem(Item item) { items.add(item); }
    public List<Item> getItems()  { return items; }
}

Not

Prototype bean'ler için Spring @PreDestroy metodunu çağırmaz. Kaynakları serbest bırakmak uygulamanın sorumluluğundadır.

4) Web Scope'ları

Aşağıdaki dört scope yalnızca Spring web uygulamalarında (servlet-based) kullanılabilir. Her biri farklı bir "ömür" tanımlar.

Request
Her HTTP isteği için bir instance
İstek tamamlandığında bean yok edilir. Formdan gelen veri işleme, request-specific doğrulama nesneleri için uygundur.
Session
Her kullanıcı oturumu için bir instance
Oturum açıldığında oluşur, kapandığında yok edilir. Kullanıcıya özgü tercihler, alışveriş sepeti gibi veriler için idealdir.
Application
Tüm web uygulaması için bir instance
ServletContext ile aynı yaşam döngüsüne sahiptir. Uygulama genelinde paylaşılan konfigürasyon veya önbellek için kullanılır.
WebSocket
Her WebSocket bağlantısı için bir instance
Bağlantı kurulduğunda yaratılır, kapatıldığında yok edilir. Tek bir WebSocket oturumuna özgü durumu yönetmek için kullanılır.

Web scope'ları için gereksinim

Request, Session, Application ve WebSocket scope'larını kullanabilmek için Spring MVC'nin RequestContextListener ya da RequestContextFilter'ın yapılandırılmış olması gerekir. Spring Boot kullananlar için bu otomatik yapılır.

5) Tüm Scope'lar — Karşılaştırma Tablosu

Scope Kaç Instance? Yaşam Süresi Ne Zaman Kullanılır?
Singleton Container başına 1 Uygulama boyunca Stateless servisler, repolar, controller'lar
Prototype Her istemde yeni Kullanıma bırakılmış State tutan nesneler, her kullanımda izole instance gerektiğinde
Request HTTP isteği başına 1 İstek tamamlanınca İstek bazlı veri işleme, form nesneleri
Session Kullanıcı oturumu başına 1 Oturum kapanınca Kullanıcıya özgü veriler, alışveriş sepeti
Application Web uygulaması başına 1 Uygulama boyunca Uygulama geneli paylaşılan veri, önbellek
WebSocket WS bağlantısı başına 1 Bağlantı kapanınca Tek WebSocket bağlantısına özgü durum

6) Scope Nasıl Tanımlanır?

@Scope anotasyonu ile

@Component
@Scope("prototype")
public class ReportGenerator { ... }
 
// Ya da sabit kullanarak (tavsiye edilir):
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ReportGenerator { ... }

Web scope'ları için

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION,
       proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserPreferences {
    private String theme = "light";
    // ...
}

proxyMode neden gerekli?

Singleton bir bean, Session/Request scope'lu bir bean'i inject ettiğinde container henüz o scope'u bilmiyor olabilir. ScopedProxyMode.TARGET_CLASS ile Spring bir proxy oluşturur; gerçek nesneye her erişimde doğru scope'tan alınır.

XML ile (klasik yaklaşım)

<bean id="userPreferences"
      class="com.example.UserPreferences"
      scope="session">
  <aop:scoped-proxy/>
</bean>

7) Hangi Scope'u Seçmeliyim?

Stateless servis mi?
Singleton — en performanslı seçim
Her kullanımda izole nesne mi?
Prototype — her inject'te yeni kopya
Tek bir HTTP isteğine özgü mü?
Request — istek biter, nesne silinir
Kullanıcı oturumuna özgü mü?
Session — oturum boyunca yaşar
Tüm kullanıcılar paylaşacak mı?
Application — global singleton benzeri
Gerçek zamanlı bağlantıya özgü mü?
WebSocket — bağlantı başına izole
"Şüpheye düştüğünüzde Singleton ile başlayın. State ihtiyacı doğunca scope'u yükseltin."

8) Sık Yapılan Hatalar

Singleton + mutable field

Thread-safety sorunu yaratır. Singleton bean'e instance state eklemeyin; ya stateless yapın ya da ThreadLocal kullanın.

Singleton → Prototype inject

Prototype bean yalnızca bir kez oluşturulur ve Singleton gibi davranır. @Lookup veya ApplicationContext.getBean() tercih edin.

Session scope + proxy eksikliği

Singleton bir bean'e Session scope'lu bean inject ederken proxyMode belirtmeyi unutursanız uygulama context yüklenemez.

Application scope ≠ Singleton

Application scope ServletContext'e bağlıdır; Singleton scope Spring container'ına. Çoklu web uygulamasında farklı davranırlar.

9) Sık Sorulan Sorular

Spring'de varsayılan bean scope nedir?

Varsayılan scope Singleton'dır. @Scope belirtilmezse Spring, container başına tek bir instance oluşturur ve tüm bileşenlerle paylaşır.

Singleton ve Application scope farkı nedir?

Singleton, Spring IoC container başına tek instance anlamına gelir. Application scope ise ServletContext başına tek instance sağlar. Tek web uygulamasında pratikte aynı davransalar da çoklu context senaryolarında ayrışırlar.

Prototype bean'de @PreDestroy çalışır mı?

Hayır. Spring, Prototype bean'lerin yaşam döngüsünü oluşturma aşamasından sonra takip etmez. @PreDestroy çağrılmaz; kaynakları serbest bırakmak uygulamanın sorumluluğundadır.

Request scope'u non-web uygulamalarda kullanabilir miyim?

Hayır. Request, Session, Application ve WebSocket scope'ları yalnızca servlet tabanlı web uygulamalarında çalışır. Bir Spring Batch veya console uygulamasında bu scope'ları kullanmaya çalışırsanız hata alırsınız.

Özel (custom) scope tanımlanabilir mi?

Evet. org.springframework.beans.factory.config.Scope interface'i implement edip ConfigurableBeanFactory.registerScope() ile kaydederek tamamen özel bir scope oluşturabilirsiniz. Spring Cloud'un @RefreshScope'u bu mekanizmanın bilinen bir örneğidir.

Etiketler: spring bean scope, singleton prototype farkı, spring request scope, spring session scope, spring web scopes, @Scope anotasyonu, spring ioc container, spring boot bean yönetimi

Latest Software Developers - Yazılım Blog Yazarı Profil Resmi

Yazar

LatestSoftwareDevelopers

Güncel yazılım teknolojilerinin takip edildiği blog.

Spring Boot ile ilgili yorumlar

Yorum Paylaş

EMail Zorunlu alanlar * *