Spring – 02 – Getting Started with Spring

Merhaba Arkadaslar
Onceki bolumde Spring dunyasina hizli bir sekilde goz atmaya calistik.
Bu bolumde ;

  • Spring Jar’larini nereden bulacagiz ? Maven ? Github ?
  • Spring Modules
  • Coupled ve Decoupled kavramlarini inceleyecegiz son olarak Spring tabanli basit bir uygulama yapacagiz.

Spring Jar’larini nereden bulacagiz ? Maven ? Github?

Main Projects linkine gidip projelerden birine girdigimizde Maven dependency tanimlari oldugunu gorebiliriz. Spring dedigimizde aklimiza genel olarak Spring Framework gelmektedir.
Aslinda , bakarsak Spring bunyesinde bir cok project mevcuttur.

Biz konumuz olan Spring Framework ‘e donelim.

Uygulamamizda Maven kullanacagiz. Boylelikle jar’larla ugrasmak zorunda kalmadan Maven bizim icin ilgili tum dependency jarlari indirecektir.
Eger Maven ‘i daha once kullanmadiysaniz endise etmeye gerek yok. Temel olarak isimize yaracak seviyede Maven ogrenmek fazla vaktinizi almayacaktir.

Turkce kaynak olarak surada yazmaya calistim , malesef resimlerin bir kismi uctu. Ingilizce kaynaklardan da biraz bakmaniz olayi anlamaniza katki saglayacaktir.
Apache Maven

Bununla birlikte jarlari kendim indirmek istiyorum derseniz bunu Github uzerinden yapabilirsiniz. Spring Github

Spring Modules

Spring Framework bunyesinde 20 civarinda module bulunmaktadir. Spring module’leri basit olarak jar dosyalaridir. Her bir module farkli bir amaca hizmet etmektedir. Projemiz icin gerekli module secip kullanmamiz yeterli olacaktir, boylelikle tum Spring Framework’unu projemize eklememize gerek kalmayacaktir.

Bu module’ler su sekilde gruplanmistir;

  • Core Container
  • Data Access/Integration
  • Web
  • AOP(Aspect Oriented Programming)
  • Instrumentation
  • Test
  • Aspects
  • Messaging

spring framework module

Bu module’lerin birbiriyle olan dependency iliskisi su sekildedir.
Spring uygulamamizda context module’u kullanmamiz gerektiginde, bu durumda core , beans , aop , expression module’leri (jarlari da gerekecek).

Spring dependency

Spring ornegine gecmeden once Coupled ve Decoupled kavramini anlayabilmek icin ornek yapalim.

Coupled

Bir uygulamada cesitli gorevleri yerine getirecek bir cok sinif bulunur. Bu siniflar birbirleriyle etkilesim haline girerek ortak bir sekilde calisirlar. Bu durumda nesneler arasinda bagimliliklar olusur. Bir sinif diger bir sinif hakkinda ne kadar fazla bilgiye sahipse o sinifa olan bagimliligi o derece artar.

Bir sinifin diger siniflari ne kadar bildigi ve sinif uyelerine nasil eristigi ile ilgilidir.

Car ve Tire adinda 2 tane sinifimiz ve Car HAS-A Tire durumu olsun. Car sinifinin yapilandiricisinda yeni bir Tire objesi olusturalim.

Car.java

package _01.coupled.model;

public class Car {

	private Tire tire;

	public Car() {
		tire = new Tire();
	}

	public void goAhead() {
		tire.useTire();
	}

}

Tire sinifinda basit olarak bir metot yazalkim. Dikkat edecek olursak bu metodu Car sinifinda yer alan goAhead isimli metottan cagirmaktayiz.

Tire.java

package _01.coupled.model;

public class Tire {

	public void useTire() {
		System.out.println("driving...");
	}

}

Car sinifi Tire sinifina bagli(coupled) durumdadir. Tire sinifinda yapilan degisiklikten Car sinifi da etkilenecektir ! Bu durumu buyuk projeler icin dusundugumuzde kontrol edilemez bir durum ortaya cikacaktir.

CoupledTest.java

package _01.coupled.test;

import _01.coupled.model.Car;

public class CoupledTest {

	public static void main(String[] args) {
		
		Car car = new Car();
		car.goAhead();

	}
}

Decoupled

Buyuyen projelerde coupling(baglilik)’ten dogacak problemlerden kurtulmak icin nesnelerin aralarindaki iliskiler bagimsiz hale getirilmelidir. Bu isleme decoupling denilir. Bu islemi yaparken arabirimlerden (interface) faydalaniriz.

Tire sinifi yerine bir arabirim (interface) tanimlayalim ; Wheel

Wheel.java

package _01.decoupled.model;

public interface Wheel {
	public void useTire();
}

Wheel arabirimini uygulayan 2 tane sinifimiz olsun ; Lassa ve GoodYear

Lassa.java

package _01.decoupled.model;

public class Lassa implements Wheel {

	@Override
	public void useTire() {
		System.out.println("Lassa driving...");
	}

}

GoodYear.java

package _01.decoupled.model;

public class GoodYear implements Wheel{

	@Override
	public void useTire() {
		System.out.println("GoodYear driving...");
	}

}

Car sinifini kullanmak yerine Vehicle adinda bir interface kullanalim. Yarin bir gun Car sinifina ek olarak Bus , Bike , Motorcycle vs siniflari da gelebilir.

Vehicle.java

package _01.decoupled.model;

public interface Vehicle {
	public void setWheel(Wheel wheel);
	public void goAhead();
}

Car sinifi Vehicle arabirimini uygulasin (implements).  Burada instance variable olarak Wheel interface tipinde bir degisken tanimlayalim.

Car.java

package _01.decoupled.model;

public class Car implements Vehicle {

	private Wheel wheel;

	@Override
	public void setWheel(Wheel wheel) {
		this.wheel = wheel;
	}

	@Override
	public void goAhead() {
		wheel.useTire();
	}
}

Wheel arabirimi yardimi ile nesneler arasinda bagimligi decoupled duruma getirdik. setWheel metoduna hangi tipte obje gecersek o sinifta yer alan useTire metodu calisacaktir.

DecoupledTest.java

package _01.decoupled.test;

import _01.decoupled.model.Car;
import _01.decoupled.model.GoodYear;
import _01.decoupled.model.Lassa;
import _01.decoupled.model.Vehicle;
import _01.decoupled.model.Wheel;

public class DecoupledTest {

	public static void main(String[] args) {
		Vehicle car = new Car();

		Wheel lassaTire = new Lassa();
		car.setWheel(lassaTire);

		car.goAhead();

		Wheel goodYearTire = new GoodYear();
		car.setWheel(goodYearTire);

		car.goAhead();
	}
}

Spring Example

Ornegimizi son olarak Spring ile gelistirelim. Spring’te metadata olarak XML ya da annotation kullanabiliriz.
Burada ilk olarak XML konfigurasyonu ile Spring ornegimizi yapacagiz.

Basit bir Spring uygulamasi yapabilmek icin minimum olarak kullanmamiz gereken dependency

pom.xml

	<properties>
                <!-- last update : 27.03.2017 !-->
		<spring.version>4.3.7.RELEASE</spring.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

spring-context , dependency olarak spring-core ,commons-logging , aopalliance gibi jar’lari da indirecektir. Maven yerine manuel olarak bunlari yapmaya calisirsak tum jarlari eksiksiz olarak eklememiz gereklidir. Bu sekilde ugrasmak yerine bu isi Maven’a birakalim ve Spring’in keyfini cikartalim.

Simdi de Spring ornegimize gecelim. Buradaki kavramlari sonraki yazilarda detayli sekilde incelemeye calisacagiz. Burada basit olarak anlamaya calisalim.

org.springframework.bean ve org.springframework.context paketleri Spring Framework’unde IoC teknigini gerceklestiren sinif/interfaceleri barindirir.

HelloSpringTest.java

package _01.hellospring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import _01.hellospring.model.Car;

public class HelloSpringTest {

	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("01.appcontext.xml");
		Car car = ctx.getBean("carId", Car.class);
		car.goAhead();

		((ClassPathXmlApplicationContext) ctx).close();
	}
}

ApplicationContext, objelerin olusturulmasindan ve birbirine baglanmasindan sorumludur. (wiring/instantiation). Yani Dependency Injection’i gerceklestirebilmek icin ApplicationContext e ihtiyacimiz vardir.
Spring birden fazla application context implamantasyonu sunar.

ClassPathXmlApplicationContext , classpath’te yer alan configurasyon dosyamizi yuklememizi (load) saglar.

FileSystemXmlApplicationContext , file system’te yer alan configurasyon dosyamizi yuklememizi (load) saglar.

ApplicationContext context = new FileSystemXmlApplicationContext("c:/appcontext.xml");

AnnotationConfigApplicationContext , XML bean tanimi yerine Java tabanli konfigurasyon yapildiginda kullanilir.

Bunlarin disinda , XmlWebApplicationContext ve AnnotationConfigWebApplicationContext Web uygulamalarinda kullanilan siniflar mevcuttur.

applicationcontext

ApplicationContext ctx = new ClassPathXmlApplicationContext("01.appcontext.xml");

ApplicationContext arabirimi org.springframework.context paketinde yer alir. Bu paket spring-context jar dosyasi icerisindedir.
ClassPathXmlApplicationContext sinifi org.springframework.context.support paketinde yer alir. Bu paket spring-context jar dosyasi icerisindedir.

ApplicationContext , BeanFactory arabiriminin alt arabirimidir. getBean metodu BeanFactory arabiriminde tanimlanmistir.

Car car = ctx.getBean("carId", Car.class);

Basic XML konfigurasyon dosyamizin icerigi su sekilde olacak ;

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

01.appcontext.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

    <bean id="carId" class="_01.hellospring.model.Car">
    	<property name="wheel" ref="lassaId"></property>
    </bean>
    
    <bean id="lassaId" class="_01.hellospring.model.Lassa"/>
    
    <bean id="goodYearId" class="_01.hellospring.model.GoodYear"/>
 

</beans>

XML tabanli konfigurasyon yaptigimizda bean etiketini kullanabiliriz. Temel olarak id ve class bilgisini vererek bean tanimini gerceklestiririz. Spring bizim icin ilgili sinif/bean tipinde objemizi olusturacaktir.

class tanimi olarak packageName.className seklinde full name yazmamiz gereklidir!

Bir diger etiket olarak propeperty etiketi yer almaktadir. Bu sayede Car sinifinda yer alan property’e ( instance variable) inject islemini gerceklestirmekteyiz. Bu etiket ref ve value attribute degerlerinden birini almaktadir. ref attribute’u ile bir baska bean’i referans olarak verebiliriz. Burada yaptigimiz ornek basit bir setter injection’dir.

Ilerleyen bolumlerde setter/constructor inject kavramlarini detayli olarak inceleyecegiz.

Projemizin gorunumu ;
NOT : Projeye ilk baslarken Spring 4.2.0 RELEASE versiyonu vardi.

project explorer

Ornegimizi calistirdigimizda ;

Lassa driving...

property wheel icin ref attribute’te id olarak goodYearId verdigimizde ;

GoodYear driving...

Github kaynak dosyalar/ source folder
leventerguder/injavawetrust-spring-tutorial

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *