• Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim
KodEduKodEdu
  • Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim

Reflection ile Dependency Injection nasıl gerçekleştirilir?

  • Posted by Rahman Usta
  • Categories backend, Genel, Uncategorized, Yazılar, Yazılım
  • Date 4 Eylül 2012

Merhaba arkadaşlar;

Bugün sizlere Java Reflection kütüphanesinden ve notasyon (annotation) bazlı yapılandırıcılardan ve ayrıca notasyon bazlı yapılandırıcılar ile basit bir Dependency Injection (Bağımlılık Zerki) uygulamasının nasıl yapılabileceğinden bahsetmek istiyorum.

Java Reflection kütüphanesi Java içerisinde 1.1 versiyonundan beri bulunuyor. Genel olarak amacı; Çalışma anında (runtime) sınıflara (Class), sınıflara ait metodlara (Methods), sınıf ya da temel tipteki değişken alanlarına (Fields) ve Annotation tanımlamalarına vs. erişmek, düzenleyebilmek, yeni bir nesne örneğini çalışma anında oluşturmak ve hatta private ve protected gibi sınırlandırılmış alanlara erişebilmektir.

Notasyon bazlı tanımlayıcılarsa, Java 1.5 sürümünden itibaren getirilen bir yenilik. @ işaretiyle başlayan notasyon tanımlayıcıları, genel olarak yapılandırma veya geliştirici tarafından tanımlanan ifadeleri uygulamalarda erişmek için kullanılıyor. Notasyonlar compile işlemi öncesinde pre-compiler araçları tarafından değerlendirilebileceği gibi, Java Reflection kütüphanesiyle runtime’ da erişilebiliyor.

Bu yazıda örnek olarak gösterilecek uygulamada; Java Reflection kütüphanesi ve notasyon bazlı tanımlayıcılar kullanılarak  “Bağımlılık Zerki (Dependency Injection)” yaklaşımının nasıl uygulandığı, temel olarak açıklanacaktır. Eğer Dependency Injection nedir diyorsanız, 1–[2] takip edebilirsiniz.

Uygulama:

Uygulamamızda Arac adında bir arayüz (interface), bu arayüzü uygulayan (implementation) 2 sınıf (Araba ve Traktor), Zerk adında bir notasyon ve bir de uygulamayı koşturmak adına App sınıfı yer alıyor.

Yukarıdaki UML diagramda bulunan bileşenlerin alanlarından, hangi metodlara ve veri alanlarına sahip olduğu anlaşılabilir. Şimdi sırayla açıklayalım.

interface Arac {

    String calis();

}

Arac isimli arayüz içinde bir adet calis() yordamı bulunuyor. Bu yordam Arac arayüzünün iskeletini oluşturuyor. Aşağıda yer alan Araba ve Traktor sınıflarıysa calis() yordamını uygulayarak String sınıfı türünden “X çalışıyor..” mesajını geri döndürüyor.

public class Araba implements Arac{

    public Araba(){
        System.out.println("Araba nesnesi oluşturuldu..");
    }

    public String calis() {
       return "Araba çalışıyor..";
    }    
}

 

public class Traktor implements Arac{

    public Traktor(){
        System.out.println("Traktor nesnesi oluşturuldu..");
    }

    public String calis() {
        return "Traktör çalışıyor..";
    }   
}

Java EE 6 veya Spring Framework teknolojileriyle uğraşanlar, @EJB, @Inject, @AutoWired, @PersistenceContext, @ManagedBean gibi notasyon arayüzleriyle enjeksiyon işlemlerinin nasıl uygulandığını bilirler. Bu uygulama ile arkaplanda bu zerk işlemlerinin nasıl yapıldığı temel olarak  anlaşılabilecektir. Notasyonlar da aslında başında @ işareti barındıran birer arayüzdür. Şimdi örnek olarak javax.ejb paketinde bulunan @EJB notasyonunu incelemeye alalım;

@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EJB {

    public String name() default "";

    public String description() default "";

    public String beanName() default "";

    public Class beanInterface() default Object.class;

    public String mappedName() default "";

    public String lookup() default "";
}

Yukarıdaki EJB notasyonunun @interface türünden olduğu görülebilir. Bu notasyonun başında tanımlı olan @Target ve @Retention da aslında Java tarafından desteklenen özel notasyonlardır. @Target notasyonunun value niteliğine tanımlanan özellikler @EJB notasyonunun nerelerde kullanılabileceği yetkisini tanımlar. Örneğin value niteliğine tanımlanan ElementType.TYPE özelliği @EJB notasyonunun sınıf, arayüz gibi birimlerin başında kullanılabileceğini yetkisini tanımlar. Diğer özellikler de adlarından anlaşılacağı üzere sırasıyla metod başında ve veri alanı(değişken) başında kullanılabilirliği tanımlar. @Retention notasyonu ise @EJB notasyonunun ne zaman erişilebilir olduğunu tanımlamaktadır. Bu örnekteki RetentionPolicy.RUNTIME ifadesi bu notasyonun çalışma anında erişilebileceğini tanımlamaktadır. Çalışma anında erişimse daha önce belirtildiği üzere Java Reflection kütüphanesiyle sağlanabilmektedir.

Notasyonlar içerisinde tanımlanan veri alanları yazılım geliştirici tarafından değer atanabilecek alanlardır. Burada örneğin name() veri alanı @EJB(name=”myEJB”) şeklinde geliştirici tarafından belirlenebilir. default niteliği ise, mevcut veri alanının varsayılan içeriğini belirtmektedir.

Şimdi sıra bizim tanımladığımız @Zerk notasyonuna geldi;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Zerk {

    public Class hangi();

}

@EJB notasyon arayüzünde açıklananlar üzere @Zerk notasyonunun çalışma anında (runtime) erişilebileceği ve yalnızca değişken alanlarında kullanılabileceği anlaşılabilir. Burada yer alan hangi() veri alanı ise, hangi sınıf türünden nesnenin zerk (injection) işlemine tabi tutulacağını tanımlamaktadır. hangi() veri alanının Class türünden bir referans aldığı da açık bir şekilde görülebilir.

Java’da herbir sınıf ya da temel tipin, bir de Class sınıf türünden bir karşılığı bulunur. Reflection ile işlemler yapabilmek için ilgili türün Class nesnesi öncelikle elde edilmelidir. Elde edilen bu nesne aracılığıyla; Sınıf içindeki veri alanlarına, kurucu metodlara, tanımlı notasyonlara ve diğer metodlara erişim sağlanabilir. Class türünden bir nesne elde edebilmek için SinifAdi.class, temelTip.class (int.class gibi) veya Class.forName(“com.kodcu.SinifAdi”); biçimleri kullanılabilir.

Şimdi uygulamayı koşturacak App sınıfına göz atalım. Yorum satırları sizlere tam olarak ne yapıldığı konusunda yardımcı olacaktır.

public class App {

@Zerk(hangi = Araba.class)  // Hangi türden nesne zerk edilecek?
public static Arac araba;

@Zerk(hangi = Traktor.class) // Hangi türden nesne zerk edilecek?
public static Arac traktor;

public static void main(String[] args) throws InstantiationException, IllegalAccessException {

// App sınıfına ait Class nesnesini çek.
Class app = App.class;

// App sınıfının veri alanlarını elde et. (araba ve traktor)
Field[] alanlar = app.getFields();

// Tüm alanları sırasıyla dön
for (Field alan : alanlar) {

// Bu alanlarda tanımlı notasyonları elde et.
Annotation[] notasyonlar = alan.getAnnotations();

// Tüm notasyonları dön (2 tane)
for (Annotation notasyon : notasyonlar) { 

// Eğer notasyon Zerk türünden ise;
if (notasyon instanceof Zerk)  
{
	// Zerk türüne aşağı doğru evir.(DownCasting)
	Zerk zerk = (Zerk) notasyon; 

	// notasyona ait hangi() veri alanı içeriğini edin.
	Class clazz = zerk.hangi();

	// Elde edilen sınıf türünden bir nesne oluştur.
	Object obj = clazz.newInstance();

	// Eğer nesne Araba türünden ise;
	if (obj instanceof Araba)
	{
		// Nesneyi Araba türüne aşağı doğru evir.(DownCasting)
		Araba arb = (Araba) obj;  

/* App içindeki hangi alan ise (araba veya traktor), o alana bu nesneyi zerk et.
*  ilk parametre hangi nesneye ait işlem gerçekleştireceğini belirler,
*  buradaki alanlar static oldukları için null geçirilir.
*  İkinci paremetre ise, zerk edilecek nesneyi bekler.
*/
	alan.set(null, arb);

		// App sınıfı içindeki araba alanına zerk edilen nesneyi çalıştır.
		System.out.println(araba.calis());

	}

	// Aynı işlemler eğer nesne Traktor türünden ise aynı şekilde gerçekleştirilir.
	if (obj instanceof Traktor)
	{
		Traktor trktr = (Traktor) obj;
		alan.set(null, trktr);
		System.out.println(traktor.calis());

	}
}}}
}}

Uygulama çıktısı:

Uygulama kaynak kodları

Tag:annotation, dependency-injection, java reflection

  • Share:
author avatar
Rahman Usta
Kodedu.com bünyesinde eğitim ve danışmanlık faaliyetleri sürdüren Rahman Usta, 2012 yılında yayına çıkan popülerJava Mimarisiyle Kurumsal Çözümler ve 2014 yılında yayınlanan Java 8 Ebook kitaplarının yazarıdır. Açık kaynak dünyasına katkı veren yazar, geliştirdiği AsciidocFX projesiyle Duke's Choice Award 2015 ödülünü kazanmıştır. Rahman ayrıca, Istanbul JUG'un ve Java standartlarını geliştiren JCP (Java Community Process)'in bir üyesidir. 2018 yılında Java Şampiyonu olarak seçilmiştir.

Previous post

Upucuz ARM Geliştirme Kiti - Kinetis KL25Z
4 Eylül 2012

Next post

Java Mimarisiyle Kurumsal Çözümler : Kurumsal Java Kitabı
16 Eylül 2012

You may also like

api-logo
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018
spring-cli-logo
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017
eureka_architecture
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017

Leave A Reply Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta listesine kayıt olun!






Gözde yazılar

Jax-RS 2 and LongPolling based Chat Application
25Haz2013
Java Collection API ve Big O Notasyonu
19Ağu2014
Java Mimarisiyle Kurumsal Çözümler : Kaynak Kodlar
09Kas2012
HTML 5 Server Sent Events on Glassfish 4
27Kas2013

Son Yazılar

  • Java’da Record’lar 27 Ocak 2020
  • Swagger Nedir? Neden kullanılır? 10 Ekim 2018
  • Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
  • Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
  • Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017

Son Yorumlar

  • YAML Nedir? Neden YAML Kullanmalıyız? için shahriyar
  • Java Persistence API Nedir? (Giriş) için Utku
  • Java 8 – CompletableFuture ile Asenkron Programlama için Rahman Usta
  • Java 8 – CompletableFuture ile Asenkron Programlama için burak
  • Arm7 Nxp 2104 işlemci ile basit bir Uygulama için Mustafa Dinc

Get Java Software

Arşivler

Bizi takip edin

React.js Eğitimi Başlıyor
11-22 Eylül, 2017
Eğitmen
Rahman Usta
İletişim

merhaba@kodedu.com

  • Hakkında
  • Gizlilik Politikası
  • İletişim
  • Referanslar
Kodedu Bilişim Danışmanlık
Cemil Meriç mah. Çelebi sok.
No:16/3 Ümraniye/İSTANBUL
Tel: 0850 885 38 65
Alemdağ V.D.: 8960484815

KODEDU © Tüm hakları saklıdır.