8 Şubat 2018 Perşembe

Spring Boot - Notlarım - 01




@EnableAutoConfiguration anatosyonu : Class düzeyinde bir anatosyondur. Maven'e veya gradle'e eklediğiniz bağımlılıklara göre Spring tahminlemelerde bulunur ve uygulamanız için oto konfigurasyonlar yapar.
Mesela spring-boot-starter-web Tomcat ve Spring-Mvc'yi uygulamanıza ekler ve web uygulamanızı gerçekleştirdiğinizi anlayıp default oto konfigurasyonlar yapar. Spring boot starter bağımlılıklar için oto konfigurasyonlar yaparken eklediğiniz third party jarlar için de bu işlemi en iyi şekilde yapmaya çalışır.

main metodu : Java uygulamalarını başlatmak için kullanılan geleneksel yaklaşım main metodunun çalıştırılmasıdır.Spring boot uygulamasıda bu noktadan başlatırlır. main metodu SpringApplication class'ını delegate eder ve run metodunu çalıştırır.SpringApplication  class'ı uygulamayı bootstrap eder ve gömülü oto configure edilmiş tomcat'i başlatır. SpringApplication clasına main metodunun bulunduğu class primary Spring Component olarak verilir.




 4.0.0
 com.example
 myproject
 0.0.1-SNAPSHOT
 
 org.springframework.boot
 spring-boot-starter-parent
 1.5.10.RELEASE
 
 

 
 org.springframework.boot
 spring-boot-starter-web
 




import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
@RestController
@EnableAutoConfiguration
public class Example {
 @RequestMapping("/")
 String home() {
 return "Hello World!";
 }
 public static void main(String[] args) throws Exception {
 SpringApplication.run(Example.class, args);
 }
}

Starters”: Spring boot bir çok starter jar'larına sahiptir. Örnek uygulamamızda pom.xml'de görebileceğiniz gibi spring-boot-starter-parent'a pom'un parent kısmında sahibiz. Bu özel starter Maven için default değerler sağlar. spring-boot-starter-parent ayrıca bağımlılık yönetimi bölümünü sağlar; böylece "kutsanmış" sürüm etiketlerini atlayabilirsiniz. Yani diğer starter bağımlılıklar için sürüm etiketi girmenize gerek kalmaz.
Diğer starterlar projenin ihtiyaçlarına göre bağımlılıkların indirilmesini sağlarlar. Mesela web uygulaması yapacaksak spring-boot-starter-web'i pom'un bağımlılıklar kısmına ekleriz.
Eğer örnek pom'umuzda  mvn dependency:tree pluginin goal'ini çalıştırısanız ,starter-web'in ihtiyacı olduğu bağımlıkları indirdiğini ve bağımlıkılık ağacını görebiliriz.(Tomcat web server'ı ve Spring Boot kendisi dahil olmak üzere.)
Offical starter'ların yazım deseni spring-boot-starter-* şeklindedir.
Eğer inherit edilmiş bağımlılıkların versiyon numarası değiştirilmek istenirse propertilerin override edilmesi yeterlidir.


 Fowler-SR2

Offical starter listesine bu yazım'dan ulaşabilirsiniz.

Java Version : Parent pom'dan default olarak Java 1.6 set edilerek gelmektedir. Java versiyonun değiştirlmesi için de propertisi override edilmelidir.

 1.8





 mvn spring-boot:run :  spring-boot-starter-parent sebebiyle POM çok faydalı olan run goal'ine sahiptir. Projenin kök dizininde maven komutu olarak  mvn spring-boot:run yazarsak projeyi bşlatabiliriz.
$ mvn spring-boot:run



Proje ayağa kalktığına göre tarayıcıdan localhost:8080 adresine girersek Hello World! çıktısını aldığı mızı görebiliriz.

Çalıştırılabilir Jar Elde Etmek : Örneğimizi, içinde çalıştırabileceğimiz tamamen kendi başına yürütülebilir bir jar dosyası oluşturarak tamamlayalım. Çalıştırılabilir jarlar (bazen "fat jar" olarak anılır), derlenmiş sınıflarınızı içeren arşivlerdir
Kodunuzun çalıştırılacağı jar tüm bağımlılıklarıyla birlikte paketlenir.
Java iç içe geçmiş jar dosyalarına izin vermez (i.e. jar dosyalarının içinde jar dosyalarının olması).
Bu self-contained uygulamanın dağıtımında sorun olabilir.
Bu problemi çözmek için,çoğu developer“uber” jarları kullanır. Bir Uber jar basitçe bağımlı olduğu jarlardan bütün classları bir jar arşivi içine paketler
Bu yaklaşımdaki problem hangi kütüphaneyi gerçekten kullandığınızı görememenizdir. Farklı jarlarda aynı sınıfı adına sahip dosyalarda kafa karıiıklığına sebep olabilimektedir. Spring boot içi içe jar işlemindeki bu problemeri çözmek için farklı bir yaklaşım sergilemektedir. Bunu ileride daha ayrıntıılı bir şekilde inceleceğiz.
Çalıştırılabilir jar elde etmek için spring-boot-maven-plugin', pom.xml'e eklememiz gerekmekte. Bu pluginin ayarları parent pom'da default değerlerini almıştır.

dependencies bölümünün altına :

 
 
 org.springframework.boot
 spring-boot-maven-plugin
 

Not : spring-boot-starter-parent POM repackage goal'i için konfigurasyonlara sahiptir.
Eğer bu parent pom'u pom'a dahil etmediyseniz bu konfigurasyonu kendiniz deklare
etmelisizniz.
pom.xml'i kaydedip proje dizininde mvn package'i çalıştırırsanız :



target klasörünün altında yaklaşık 10 MB boyutunda myproject-0.0.1-SNAPSHOT.jar dosyasının oluştuğunu göreceksiniz.
Eğer jar içindeki dosyalara bakmak istiyorsanız :

 jar tvf target/myproject-0.0.1-SNAPSHOT.jar

komutunu kullanabilirsiniz.

Ayrıca spring-boot'un repacakeg ettiği dosya haricinde maven'in oluşturduğu orjinal jar dosyası olan
myproject-0.0.1-SNAPSHOT.jar.original dosyasını da target klasörü altında görebilirsiniz.
Uygulamayı çalıştırmak içim java -jar komutunu kullanıyoruz :


Uygulamayı kapatmak için Ctrl + C tuşlarını kullanabiliriz.


main class'ı konumlandırmak :  Main class'ı kök pakete koymak tercih edilmelidir. Mesela  eğer JPA uygulaması yazıyorsunuz @EnableAutoConfiguration anatasyonu main class'ın bukunduğu kök dizinden başlayarak paketlerde @Entity class'larını arar.
Ayrıca kök dizinde olduğunuz için componentleri tarayan @ComponentScan anatasyonuna ilave olarak base pacakage attribut'ünü girmenize gerek kalmaz.

Örnek bir layout :





package com.example.myproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan

public class Application {
 public static void main(String[] args) {
 SpringApplication.run(Application.class, args);
 }
}

Configuration Class'ı : Spring boot uygulaması yazarken Java-based konfigurasyon en populer olandır. Elbetteki bu işlem XML temelli olarak yapılabilmekte ise de, konfigurasyon yapılacak (container için bean üretme) işini class'lara  @Configuration anatasyonu koyarak gerçekleştirirz.
Birincil (primary) kanfigurasyon sınıfı adayımız main metodunun bulunduğu sınıftır.

Enable* ile başlayan anatasyonlar konfigurasyon sınıfına daha önce tanımlanmış java konfigurasyon sınıflarının otomatik olarak import edilmesine güzel bir örnektir.

Ayrıca bir konfigurasyon sınıfı diğer konfigurasyon sınıfını @Import anatasyonuyla import ederek import ettiği konfigurasyon sınıfında yaratılan beanleri kendi konfigurasyon beanlerini şekillendirmek için kullanabilirler. Ayrıca bu işlemi alternatif olarak konfigurasyon sınıfında @ComponentScan anatasyonu kullanarak diğer konfigurasyon sınıfında bulunan beanleri kullanabilme becersi sağlarlar.

Ayrıca bir configurasyon sınıfında @ImportResource anatasyonuyla XML ile konfigure edilmiş bean'lerde import edilebilmektedir.

Auto-configuration : Spring boot projeye eklediğiniz jar'ları otomatik olarak konfigure etmeye çalışır. Örneğin kendi Datasource bean'inizi tanımlarsanız varsayılan gömülü db Datasurce tanımlamanız yok olur.
Eğer uygulamanızın auto configurationlarını görmek isterseniz uygulamanızı --debug modda çalıştırıp ve loglardan auto configurationlarınızı görebilirsiniz.

Eğer bazı class'ların auto configure edilmesini istemiyorsanız @EnableAutoConfiguration anatosyonuna exclude attribute ile classın adını vererek class'ın auto configure edilmesini önleyebilirirsiniz.(Ayrıca property seviyesinde de bu işlemi yapmak mümkündür)
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}


Spring Bean'leri ve Dependency Injection : Spring Boot'da beanleri tanımlamak için Spring'de kullandığımız teknikleri kullanmakta özgürüz. Genel olarak  @ComponentScan ile beanleri bulup @Autowired ile bu beanleri uygulamamıza inject ederiz.

Eğer yapınız Spring boot uygulamanızın main methodunun bulunduğu Applicaition classı ise bu sınıfa  @ComponentScan ekleyip tüm @Component, @Service, @Repository, @Controller gibi componentleri uygulamanıza register edebilirsiniz.

Tek Constructor ve field'ın final olması :  Eğer compnent'iniz tek constructor'a sahipse @Autowired'a ihtiyacınız kalmayacaktır : (İlk örenkteki final field için @Autowired kullanımına gerek kalmayacaktır)
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
 private final RiskAssessor riskAssessor;
 @Autowired
 public DatabaseAccountService(RiskAssessor riskAssessor) {
 this.riskAssessor = riskAssessor;
 }
 // ...
}

@Service
public class DatabaseAccountService implements AccountService {
 private final RiskAssessor riskAssessor;
 public DatabaseAccountService(RiskAssessor riskAssessor) {
 this.riskAssessor = riskAssessor;
 }
 // ...
}




@SpringBootApplication anatasyonu kullanımı :  Eğer sınıfınızda @Configuration, @EnableAutoConfiguration ve@ComponentScan anatasyonlarını beraber kullanıyorsanız tüm bu
üç anatasyonu karşılıyan @SpringBootApplication anatasyonunu kullanabilirsiniz. Bu şekilde kullanımda  @Configuration ve @EnableAutoConfiguration'ın attribute'larını @SpringBootApplication'da özelleştirebilirisiniz.

package com.example.myproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {
 public static void main(String[] args) {
 SpringApplication.run(Application.class, args);
 }
}


Uygulamanızı Çalıştırmak : Burada oluşturduğunuz jar dosyalarınızı çalıştırmaktan bahsedeceğiz. Eğer uygulamanız web uygulaması ise içinde gömülü tomcat olacaktır. Eğer war şeklinde paketlemeyi seçtiyseniz uygulama sunucunuzun war'ı nasıl çalıştırdığına bakmanız gerekmektedir.

Eğer uygulamanızı ide'den çalıştırıyorsanız :

Uygulamanızı maven veya gradle uygulaması olarak import ettikten sonra run as java program şeklinde çalıştırırsınız. Eğer uygulamanız web uygulaması ise ve iki kez kazara çalıştırırsanız port already in use hatası alırsınız.

Paketlenmiş uygulamayı çalıştırıyorsanız :

Eğer uygulamanızı maen veya gradle ile çalıştırılabilir paket haline getirdiyseniz, uygulamanızı  java -jar komutuyla çalıştırabilirsiniz. Öreneğin :
java -jar target/myproject-0.0.1-SNAPSHOT.jar
Aynı şekilde uygulamanızı uzaktanda çalıştırabilirsiniz :
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \ -jar target/myproject-0.0.1-SNAPSHOT.jar

Maven plugin'i ile çalıştırmak :
Uygulamanızı paketlemeden maven plugin'i ile de çalıştırabilirsiniz.
$ mvn spring-boot:run 

Gradle ile çalıştırmak :
$ gradle bootRun 

Hot swapping : Spring boot uygulamaları sade Java uygulamaları olduğundan JVM hot-swapping bu noktada etkili oluyor. JVM hot-swapping'in bytecode değişiminde swapping kabiliyetleri sınırlı olduğundan daha derin çözümler için JRebel veya Spring Loaded projeleri bu noktada daha etkili olmaktadır. Ayrıca spring-boot-devtools modülü hızlı uygulama restart'larında destek vermektedir.


Kaynak : https://docs.spring.io/spring-boot/docs/current/reference/pdf/spring-boot-reference.pdf


0 yorum: