Spring Framework Java Sınıfları ile Konfigürasyon
Yazılım teknolojilerinde konfigürasyon işlemlerinde büyük çoğunlukla XML teknolojilerinden faydalanılmaktadır. Bunu Java programlama dili için düşünürsek, Apache Maven aracı için pom.xml, Web uygulamaları için web.xml, JavaServer Faces için faces-config.xml gibi yapılandırıcı dosyalar konfigürasyon maksatlı kullanılmaktadır .
Spring Framework’ de XML ve Java tabanlı yapılandırıcılarla kendi ekosistemini geliştiricilere açmaktadır. XML tabanlı Spring yapılandırıcılar genel olarak aşağıdaki işlemlere imkan sunmaktadır.
- IOC konteyner’in yöneteceği nesnelerin (Spring Bean) tanımlanması,
- Spring nesneleri arasındaki bağın kurulması (Setter veya Constructor Injection ile),
- Tanımlı nesnelere dönük veri alanlarının düzenlenmesi,
- Örneğin bir Datasource nesnesinin url, username, password gibi alanlarının düzenlenmesi.
- Yetkilendirme yapılması,
- Şu paket içindeki tüm sınıflarda Spring notasyonları taransın
- Transaction yönetimi aktifleştirilsin
- Notasyon kullanımı aktifleştirilsin
- AspectJ proxy kullanımı aktifleştirilsin, gibi.
Spring Framework’ün 3.0 versiyonu ile beraber, XML tabanlı yapılandırmaya alternatif olarak Java sınıfları üzerinden yapılandırma desteği de getirildi. An itibariyle XML tabanlı yapılandırıcılarda yapılabilen herşey, aynı zamanda Java taraflı konfigürasyon sınıflarında da yapılabilmektedir. Hangisi daha iyi, hangisi kullanılmalı gibi konuları sizlere bırakıyor ve kullanım örneklerini paylaşmak istiyorum.
Paylaşacağımız uygulamada Arac arayüzü türünden bir Araba sınıfı ve Arac arayüzü türünden nesneleri yöneten Galeri sınıfı bulunmaktadır.
public interface Arac {
public void calis();
}
Arac olduğunu iddaa eden her sınıf, çalışmalıdır.
public class Araba implements Arac {
@Override
public void calis() {
System.out.println("Araba çalışıyor..");
}
}
Araçlar yönetilirken galerilerden faydalanılabilir.
public class Galeri {
private Arac arac;
public Arac getArac() {
return arac;
}
public void setArac(Arac arac) {
this.arac = arac;
}
}
UML diagramına bakıldığında, Spring nesnesi olma adayı olarak 2 sınıf gösterilebilir. Araba ve Galeri. Şimdi bu nesneleri XML ve Java taraflı konfigürasyonlarla yönetebiliriz. Daha evvel yayınlanan Yöntem 1 ve Yöntem 2 için https://kodedu.com/2013/09/spring-framework-xml-ile-konfigurasyon/ takip edebilirsiniz.
Yöntem 3
Bir önceki iki yöntemde uygulamamız bir biçimde XML yapılandırıcı dosyasını kullanmaktaydı. Eğer hiç XLM yapılandırıcılarına bulaşmak istenilmiyorsa Spring 3.0 ile sisteme katılan AnnotationConfigApplicationContext nesnesi kullanılabilir. Bu yöntemde Yöntem 2 içinde @Component ve @Autowired notasyonları ile yapılandırılan Galeri ve Araba sınıfları aynen kullanılmaktadır. Tek değişim konteynerin oluşturulduğu kısımda gerçekleşmektedir.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Galeri.class,Araba.class);
context.refresh();
Galeri galeri = context.getBean("galeri", Galeri.class);
galeri.getArac().calis();
AnnotationConfigApplicationContext nesneleri, doğrudan notasyon uygulanmış Java sınıfları ile Spring konteyneri başlatabilmektedir. Fakat bunun için @Component notasyonu uygulanmış sınıflar AnnotationConfigApplicationContext#register metodu üzerinden tanıtılması gerekmektedir. AnnotationConfigApplicationContext#register metoduna birden fazla sınıf virgül (,) ile ayrılarak eklenebilmektedir. Bu örnekte Galeri ve Araba sınılarının class tipleri kayıt ettirilmiştir. Context üzerine yeni eklenen sınıfların tamamen devreye sokulması ve işlenmesi için ise AnnotationConfigApplicationContext#refresh metodu çağrılmalıdır. Bu adımlardan sonra konteyner üzerinde Spring nesneleri tamamen XML bağımsız olarak tanıtılmış ve erişilebilir olur.
AnnotationConfigApplicationContext#register metodu bir elin parmaklarını geçmeyek belirtimler için uygundur fakat, yüzlerce Spring komponentinin bulunabileceği bir uygulamada tek tek eklemek biraz sancılı olabilir. Bunun için register metodu yerine, bir paket dizini altındaki tüm sınıfları tarayacak keşif yapan AnnotationConfigApplicationContext#scan metodu kullanılabilmektedir.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.kodcu.noxml"); // Dikkat
context.refresh();
Galeri galeri = context.getBean("galeri", Galeri.class);
galeri.getArac().calis();
Örneğin yukarıdaki kullanımda “com.kodcu.noxml” paketi altındaki tüm sınıflarda Spring Bean olma yetisine sahip notasyonlu sınıflar taranarak bulunur ve Spring konteyner XML bağımsız olarak ayaklandırılmış olur.
Yöntem 4
Bir önceki Yöntem 3’te XML bağımsız olarak Spring konteyner başlatılabilir ve @Component benzeri notasyonlara sahip sınıflardan Spring nesneleri konteynere dahil edilebilir. Fakat bu kullanımın en büyük eksiği yapılandırmadan ziyade tanımlama tabanlı komponentlerin oluşmasıdır.
Örneğin bir XML yapılandırma dosyasında, Spring konteyner tarafından yönetilebilir bir Datasource nesnesi, aşağıdaki gibi tanımlanabilir ve yapılandırılabilirdir.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:hsqldb:mem:."/>
<property name="password" value=""/>
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="username" value="sa"/>
</bean>
Fakat bu tip bir Spring Bean tanımlamasını @Component notasyonu ile dikişsiz sağlamak mümkün değildir. Fakat dataSource id’li bu Spring nesnesi @Component notasyonu ile aşağıdaki gibi tanımlanabilir ve yapılandırılabilir.
@Component
public class KodcuDataSource extends DriverManagerDataSource {
public KodcuDataSource() {
setUrl("jdbc:hsqldb:mem:.");
setUsername("sa");
setPassword("");
setDriverClassName("org.hsqldb.jdbcDriver");
}
}
Fakat bu kullanım biçimi sık sık tekrarlandığında emek israfı yaptığınız hissi sizlerde uyanabilir.
AnnotationConfigApplicationContext nesneleri doğrudan @Component benzeri notasyonlarla çalışabildiği gibi, Spring 3.0 versiyonuyla birlikte gelen Java taraflı @Configuration sınıfları ile de çalışabilmektedir. Bir Spring uygulaması XML yapılandırıcılarla nasıl konfigüre ediliyorsa, eşdeğer olarak Java @Configuration sınıflarında da istenilen işlemler yapılabilmektedir.
Java sınıfları halinde bulunan konfigürasyon sınıfları asgari ölçekte bir sınıf başına @Configuration notasyonu uygulanarak oluşturulurlar. Örneğin;
@Configuration
@ComponentScan(basePackages = "com.kodcu.conf")
public class KodcuConfig {
//...
}
KodcuConfig isimli Spring konfigurasyon sınıfı aşağıdaki XML içeriğiyle eşdeğerdir.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.kodcu.conf"/>
</beans>
KodcuConfig konfigürasyon sınıfı şu noktada “com.kodcu.conf” paketi altında yer alan Spring komponentlerini konteyner içerisine katabilir ve yönetebilirdir. @Configuration notasyonu uygulanan Spring yapılandırıcı sınıfları AnnotationConfigApplicationContext sınıfının yapılandırıcısı üzerinden tanıtılabilir.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(KodcuConfig.class);
Galeri galeri = context.getBean("galeri", Galeri.class);
galeri.getArac().calis();
@Configuration sınıfları doğrudan Spring komponent notasyonlarıyla çalışabileceği gibi (@Component, @Repository gibi), XML yapılandırıcılara benzer bir şekilde konfigürasyon yapmaya olanak tanır. Örnek olarak Galeri ve Araba sınıfları içerisindeki @Component ve @Autowired notasyonları silinirse, bu bileşenler ve aralarındaki bağ, doğrudan @Configuration sınıflarında kurulabilir.
@Configuration
public class KodcuConfig {
@Bean(name = "araba")
public Arac getAraba() {
return new Araba();
}
@Bean(name = "galeri")
public Galeri getGaleri() {
Galeri galeri = new Galeri();
galeri.setArac(getAraba());
return galeri;
}
}
@Configuration sınıflarında Spring Bean tanımlanırken @Bean notasyonundan faydalanılmaktadır. @Bean notasyonu XML taraflı elemanıyla benzer amaçla kullanılmaktadır. @Bean notasyonu uygulandığı metottan döndürülen nesneyi bir Spring nesnesi olarak konteynere katmaktadır. @Bean notasyonunun “name” niteliği üretilen nesnenin id bilgisine denk gelirken, hiç tanımlanmadığı takdirde id bilgisi doğrudan metod adı (getAraba, getGaleri gibi) ile denk olmaktadır. Bu kullanım ile örneğin KodcuDataSource sınıfında yapıldığı gibi bir Datasource nesnesi üretilmek isteniyorsa, bu gibi işlemlerde @Configuration sınıflarını kullanmak daha fazla esneklik sunacaktır.
@Bean
public DataSource getDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:hsqldb:mem:.");
dataSource.setUsername("sa");
dataSource.setPassword("");
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
return dataSource;
}
Konfigürasyon sınıflarının kullanımının en önemli avantajı XML yapılandırma dosyalarında elde ettiğiniz tüm esnekliği, Java taraflı konfigürasyon ile de elde edebilmektir.
Uygulama örneklerine bu bağlantıdan erişebilirsiniz.
Tekrar görüşmek dileğiyle.