Bu yazımda beanleri tanıttığımız xml dosyası üzerinden autowiring tanımlamalarını anlatacağım.
Neden autowiring kullanırız?
Önceki yazılarımda Spring üzerinde Dependency Injection konusuna değindiğimde, bağımlılıkları enjekte ederken Spring xml dosyasında bean bağımlılıklarında <constructor-arg>, <property> attributlerini kullanıyorduk. Bu işlem yazılımımız büyüdükçe tekrar tekrar aynı şeyleri Spring xml dosyasına girmemize neden olacak ve yönetilmesi zorlaşmaya başlayacaktır.
Autowiring ile bağımlılıklar otomatik olarak injecte edilerek xml bağımlılığı en aza indirgenmektedir.
Autowiring Çeşitleri
1) Auto-wire no:
Varsayılandır. Bağımlılıklar tek tek yazılır. Yani bean'leri bağlamak için "ref" attribute kullanılır.
<bean id="musteri" class="com.serdarkocerr.Customer">
<property name="kisi" ref="kisi" />
</bean>
<bean id="kisi" class="com.serdarkocerr.Person" />
2) Auto-wire byName:
Autowiring işlemi, beanı isime göre otomatik olarak bağlar.
Aşağıdaki örneği inceleyelim.
public class Ogrenci {
private String ogrenciad;
private String ogrencisoyad;
private String numara;
private String okulad;
public String getOgrenciad() {
return ogrenciad;
}
public void setOgrenciad(String ogrenciad) {
this.ogrenciad = ogrenciad;
}
public String getOgrencisoyad() {
return ogrencisoyad;
}
public void setOgrencisoyad(String ogrencisoyad) {
this.ogrencisoyad = ogrencisoyad;
}
public String getNumara() {
return numara;
}
public void setNumara(String numara) {
this.numara = numara;
}
public String getOkulad() {
return okulad;
}
public void setOkulad(String okulad) {
this.okulad = okulad;
}
}
package com.serdarkocerr.SpringExample; public class Ders { /*AutoWiring Ozelligi XML de*/ private Ogrenci ogrenci; private String dersad; public Ogrenci getOgrenci() { return ogrenci; } public void setOgrenci(Ogrenci ogrenci) { this.ogrenci = ogrenci; } public String getDersad() { return dersad; } public void setDersad(String dersad) { this.dersad = dersad; } }
İki tane class tanımlandı. Dikkat edersek Ders class'ının değişkeni Ogrenci nesnesi şeklinde tanımlanmış. Bu durumda öğrenci nesnesi tanımlanmalıdır ama dependency injection gereği bu nesne class'ın içinde tanımlanmaz. Dışarıdan tanımlanır verilir.
Spring'te bu tanımlamalar xml üzerinden yapıldığını biliyoruz. Aşağıda verilen xml dosyasını inceleyelim.
Spring-Module.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="ogrenci" class="com.serdarkocerr.SpringExample.Ogrenci"> <property name="ogrenciad" value="Serdar" /> <property name="ogrencisoyad" value="Kocer" /> <property name="numara" value="821" /> <property name="okulad" value="Arifiye AOL" /> </bean> <bean id="ders" class="com.serdarkocerr.SpringExample.Ders" autowire="byName"> <property name="dersad" value="Matematik" /> </bean> </beans>
Kırmızı bold alanlara dikkat et!
Spring-Module.xml dosyasını inceledeğimizde Ders class'ından tanımlanan bean'de bir autowiring işlemi olduğu görülüyor. Yani Ders class'ı içerisinde değişken olarak bir class tipinde nesne tanıtılmış. Autowire = "byName" olduğundan Ders class'ında tanımlanan nesne tipindeki değişkenin ismi ile bean tanımlamasında kullanılan id aynı olmalıdır.
Dikkatli incelersek Ders class'ının hem Set fonksiyonunda hemde nesne tanımlamasında
Ogrenci ogrenci
şeklinde tanımlanmış.
Detay Bilgi:
Auto-wire işlemi olabilmesi için set/get metodları tanımlanmalıdır. Hem auto-wire eden hemde auto-
wire edilen classların ikisinde birden bu tanımlama olmalıdır. byName ile yapılırken Setter/Getter
üzerinden yapılır.
Yani setter metodunun parametresi ile bean id aynı isimde olmalıdır. Ayrıca class değişkeninin
ismide aynı olmalıdır.
3) Auto-wire byType:
Bir bean ile auto-wire işlemi nesne tipine göre olur.
Aşağıdaki örneği inceleyelim.
Ogrenci ve Ders class'ları yukarıdaki gibidir bir değişiklik yoktur. Sadece xml de aşağıdaki değişiklikler olmuştur.
Spring-Module.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="ogr" class="com.serdarkocerr.SpringExample.Ogrenci"> <property name="ogrenciad" value="Serdar" /> <property name="ogrencisoyad" value="Kocer" /> <property name="numara" value="821" /> <property name="okulad" value="Arifiye AOL" /> </bean> <bean id="ders" class="com.serdarkocerr.SpringExample.Ders" autowire="byType"> <property name="dersad" value="Matematik" /> </bean> </beans>
Kırmızı bold alanlara dikkat et!
ByType ile autowiring işleminde Ders class'ı içerisinde tanımlanan Ogrenci tipindeki nesne ile autowire işlemi, Ogrenci tipine yani nesnenin tanımlanma tipine göre olur. Dikkat edilirse id diğer örnekten farklı çünkü burada byName değilde byType şeklinde autowiring işlemi var.
4) Auto-wire constructor:
Constructor üzerinden autowiring işlemi yapılır.
public class Ogrenci {
private String ogrenciad;
private String ogrencisoyad;
private String numara;
private String okulad;
public String getOgrenciad() {
return ogrenciad;
}
public void setOgrenciad(String ogrenciad) {
this.ogrenciad = ogrenciad;
}
public String getOgrencisoyad() {
return ogrencisoyad;
}
public void setOgrencisoyad(String ogrencisoyad) {
this.ogrencisoyad = ogrencisoyad;
}
public String getNumara() {
return numara;
}
public void setNumara(String numara) {
this.numara = numara;
}
public String getOkulad() {
return okulad;
}
public void setOkulad(String okulad) {
this.okulad = okulad;
}
}
package com.serdarkocerr.SpringExample;
public class Ders {
/*AutoWiring Ozelligi XML de*/
private Ogrenci ogrenci;
private String dersad;
public Ders(Ogrenci ogrenci) {
super();
this.ogrenci = ogrenci;
}
public Ogrenci getOgrenci() {
return ogrenci;
}
public String getDersad() {
return dersad;
}
public void setDersad(String dersad) {
this.dersad = dersad;
}
}
Ders class'ına dikkat edersek Set methodu yok. Bunun yerine constructor ile Ogrenci nesnesini set edeceğiz.Spring-Module.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="ogr" class="com.serdarkocerr.SpringExample.Ogrenci"> <property name="ogrenciad" value="Serdar" /> <property name="ogrencisoyad" value="Kocer" /> <property name="numara" value="821" /> <property name="okulad" value="Arifiye AOL" /> </bean> <bean id="ders" class="com.serdarkocerr.SpringExample.Ders" autowire="constructor"> <property name="dersad" value="Matematik" /> </bean> </beans>Kırmızı bold alanlara dikkat et!
Spring-module.xml içerisine bakacak olursak autowire işlemi "constructor" olarak seçilmiş. Bu demek oluyor ki Ders class'ı içerisine bir nesneye constructor üzerinden autowire işlemi uygulanacak.
4) Auto-wire autodetect:
Default olarak constructor üzerinden autowiring işlemi yapar. Eğer constructor yoksa byType olarak autowiring işlemi yapar.
Ogrenci ile Ders class'ı auto-wire constructor'daki gibi olsun.
Spring-Module.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="ogr" class="com.serdarkocerr.SpringExample.Ogrenci"> <property name="ogrenciad" value="Serdar" /> <property name="ogrencisoyad" value="Kocer" /> <property name="numara" value="821" /> <property name="okulad" value="Arifiye AOL" /> </bean> <bean id="ders" class="com.serdarkocerr.SpringExample.Ders" autowire="autodetect"> <property name="dersad" value="Matematik" /> </bean> </beans>Kırmızı bold alanlara dikkat et!
Spring-Module.xml'e dikkat edilirse autowire "autodetect" olarak seçilmiş durumdadır. Autodetect'te default olarak constructor üzerinden eğer constructor yoksa byType olarak autowiring işlemi yapılır.
Bu örnekte constructor üzerinden autowire yapacaktır.
ÖNEMLİ DETAY:
Mesela Databaseye Spring MVC XML konfigürasyonu ile veri kaydedeceğiz. BU Databasede kullanmak üzere DAO Design Pattern'nini kullanacağız. DAO Imp sınıfında xml de tanıttığımız bir değişkeni @Autowired ile bağladık. Ardından bu DAOImp sınıfından bir nesne yaratmak ve databasete kayıt işlemi gerçekleştirmek istiyoruz. Bu nesne yaratımını eğer new(); ile yaparsak içerisinde kullandığımız @Autowired edilen nesne xml de verdiğimiz bean değerlerini alamaz. Çünkü bu durumda yani new ile yaratma durumunda nesneyi Spring kontrol etmez yani konfigüre edemez. Kendimiz yaratmış oluruz. Bunun önüne geçmek için DAOImp sınıfınıda xml de bean olarak tanıtıyoruz ve new(); olarak kullanacağımız yerde new(); yerine @Autowired ile DAOImp sınıfını yaratıp içerisinde bulunan @Autowired değişkenlerinin Spring tarafından xml de belirtilen bean değerlerini almasını sağlarız.
Yani sonuç olarak, bir nesneyi yaratırken eğer içerisinde @Autowired şeklinde Spring tarafından kontrol edilen(inject edilen) değişkenler, nesneler vs. varsa yaratacağımız nesneyi new(); ile değilde xml de bean olarak tanıtıp, kullanılacak yerde nesne deklare edilip ardından @Autowired yapılmalıdır.
Yoksa NullPointerException hatası alınır.
https://stackoverflow.com/questions/35302501/jdbctemplate-is-null-and-throws-null-pointer-exception
http://forum.spring.io/forum/spring-projects/data/69318-getting-null-pointer-exception-while-using-jdbc-template
Kaynaklar:
http://www.mkyong.com/spring/spring-auto-wiring-beans-in-xml/
http://blog.burakkutbay.com/spring-dersleri-autowiring-nedir-kullanimi.html/
Hiç yorum yok:
Yorum Gönder