Spring Boot Nedir? Kurulumu ve Kullanımı

Paylaş

Sağlamış olduğu yapı sayesinde kolay ve hızlı Spring tabanlı uygulamalar geliştirmede kullanılan Spring Boot nedir, kurulumu ve kullanımı yer alıyor.

Spring Boot nedir?

Spring framework ile geliştirilen, güçlü varsayılan-otomatik ayarları sayesinde kolay ve hızlı Spring tabanlı uygulama yapımı için geliştirilmiş bir projedir.

Spring framework hakkında detaylı bilgi almak için Spring framework yazıma bakmalısın.

Neden Spring Boot?

Spring framework kullanılarak geliştirilen görsel, web tabanlı veya özel kütüphane temelli uygulamalar birçok ayarın belirlenmesine ihtiyaç duyar.

Ayarlara örnek olarak; bean arama yolunun belirlenmesi (@ComponentScan), web uygulamasına ait görüntüleme motorunun belirlenmesi (template engine), Spring Web MVC, Spring Security gibi projelerin ihtiyaç duyduğu standart ifadeler (@EnableWebMvc, @EnableWebSecurity) verilebilir.

Ayarlar bir süre sonra her proje için benzerlik göstermeye başlar ve geliştirme süresini uzatır.

Spring Security projesinin kullanımı için örnek-dummy kullanıcı oluşturulmasına, Spring Data için geliştirme ortamında gömülü veritabanı kullanımına sıklıkla ihtiyaç duyulur.

Spring Security hakkında detaylı bilgi almak için Spring Security yazıma bakmalısın.

Spring Data hakkında detaylı bilgi almak için Spring Data yazıma bakmalısın.

Ayarların belirlenmesi sırasında genellikle Spring platformundaki projede yer alan sınıflar kullanılır ve değer ataması anahtar-değer olarak yapılır.

@Bean
public ViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/WEB-INF/views/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
}

Spring Boot uygulama türüne göre uygulama ayarlarını varsayılan-otomatik ayar özelliği ile yaparak daha hızlı uygulama geliştirmeyi sağlar.

Ayrıca sağladığı geniş ve dinamik ayar tanımlama özelliği sayesinde varsayılan veya uygulama içerisinde kullanılacak ayarların kolay bir şekilde belirlenmesini sağlar.

Spring Boot kurulumu

Spring Boot kurulumu uygulama türüne ve kullanılacak olan kütüphaneye göre farklılık gösterir.

Spring Initializr

Spring Boot projesi oluştururken genellikle Spring Initializr kullanılır.

https://start.spring.io/

Spring Initializr proje oluştururken aşağıdaki seçenekleri dinamik olarak belirlemeyi sağlar.

  • İnşa aracını (Maven, Gradle),
  • JVM dilini (Java, Kotlin, Groovy)
  • Spring Boot sürümünü
  • Paketleme türünü (jar, war)
  • Java sürümünü
  • Projede kullanılacak olan kütüphaneleri/bağımlılıkları

Proje yapısını görüntülemek için Explore, proje dosyalarını indirmek için Generate kullanılır.

IDE

Spring Boot projesi oluşturmanın diğer bir yolu ise NetBeans, IntelliJ IDEA, Eclipse veya Visual Studio Code gibi editörleri kullanmaktadır.

Bazı editörler varsayılan olarak Spring Boot eklentisi ile birlikte gelirken bazı editörlere Spring Boot eklentisinin yüklenmesi gerekebilir.

NOT: Editörler Spring Boot projesini üretirken Spring Initializr sayfasını kullanır.

Spring Boot CLI

Spring Boot projesi oluşturmanın pek tercih edilmeyen başka bir yolu ise Spring Boot kullanılarak geliştirilen Spring Boot CLI aracının kullanımıdır.

Araç işletim sistemine göre SDKMAN, brew, scoop vb. paket yöneticisi veya dosya olarak indirilip işletim sistemi ortam değişkenine eklenerek kullanılır.

Aşağıdaki komut Spring Web, Spring Data projesini kullanan spring-boot-projem projesi oluşturacaktır.

spring init --dependencies=web,data-jpa spring-boot-projem

NOT: Spring Boot CLI proje oluştururken Spring Initializr sayfasını kullanır.

Kurulum ayarları

Spring Boot sağladığı geniş ve dinamik ayar tanımlama özelliği ile birlikte geniş kurulum ayarlarına sahiptir.

Çokça kullanıldığından dolayı varsayılan olarak gelen Maven inşaa aracı ve Java dili kullanılacaktır.

Spring Boot projesi yapısında maven dizin yapısı, ayar dosyası ve yaşam döngüsünü kullandığından dolayı maven hakkında bilgi almak faydalı olacaktır.

Maven hakkında detaylı bilgi almak için Maven yazıma bakmalısın.

Proje oluşturulduğunda proje yapısında yer alan pom.xml dosyasının içeriği aşağıdaki gibi olacaktır.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--Spring boot(parent pom) ayarları-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--Proje bilgileri-->
    <groupId>com.yusufsezer</groupId>
    <artifactId>MerhabaSpringBoot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>MerhabaSpringBoot</name>
    <description>Spring Boot kurulumu</description>

    <!--Maven/Proje ayarları-->
    <properties>
        <java.version>21</java.version>
    </properties>

    <!--Bağımlılıklar-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--Maven/Spring araçları-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring Boot bağımlılık, maven ve diğer ayarları parent pom özelliğini kullanarak varsayılan-otomatik olarak belirler.

Parent POM

Tüm ayarları görüntülemek için IDE/editör kullanmak veya aşağıdaki komut satırının proje dizininde çalıştırılması yeterli olacaktır.

mvn help:effective-pom

Ayarlar incelendiğinde properties alanında ayar listesi,

<properties>
    ...
    <h2.version>1.4.200</h2.version>
    ...
    <mysql.version>8.3.0</mysql.version>
    ...
</properties>

maven araçları bölümünde çeşitli değişkenlerin kullanıldığı görünecektir.

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>${start-class}</mainClass>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>

Spring Boot bu ayarları belirleyerek önceden belirlenmiş kütüphaneler için sadece bağımlılığın eklenerek kullanılmasını sağlar.

Maven/Proje ayarları

MySQL kullanan bir proje için aşağıdaki tanımın dependencies alanına eklenmesi yeterli olacaktır.

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

Spring Boot kullanılacak olan MySQL arabirimine ait sürüm bilgisini parent pom dosyasından alarak sürümler arasındaki uyuşmazlığı ortadan kaldıracaktır.

Sürüm bilgisi pom.xml dosyasında yer alan properties alanına aşağıdaki ayarın eklenmesi ile düzenlenebilir.

<properties>
    <mysql.version>8.3.0</mysql.version>
</properties>

Diğer bir yöntem ise dependency alanına version alanının eklenmesidir.

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.3.0</version>
    <scope>runtime</scope>
</dependency>

NOT: Sürüm uyuşmazlığı gibi durumlar için varsayılan sürümü kullanmak faydalı olacaktır.

Spring Boot kullanılacak kütüphanelerin yanında Java sürümü, maven eklentilerine ait değerleri dinamik olarak belirlemeyi sağlar.

<!--Maven/Proje ayarları-->
<properties>
    <java.version>21</java.version>
    <start-class>com.yusufsezer.DemoApplication</start-class>
</properties>

Bağımlılıklar

Spring Boot geliştirilecek olan proje türüne göre ihtiyaç duyulan ve kullanılacak kütüphaneleri spring-boot-starter ön eki altında toplar.

Örneğin; Web tabanlı bir uygulama geliştirilmek istenildiğinde spring-boot-starter-web paketinin bağımlılık olarak eklenmesi yeterli olacaktır.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot web tabanlı uygulamanın geliştirilmesi ve çalıştırılması için ihtiyaç duyulan kütüphaneleri (spring-web, spring-webmvc, tomcat-embed vb.) sağlayarak uygulamanın geliştirilmesini ve çalıştırılmasını sağlar.

Bazı paketler ve karşılıkları aşağıdaki gibidir.

  • spring-boot-starter-web – web tabanlı uygulama
  • spring-boot-starter-security – spring security
  • spring-boot-starter-data-jpa – spring data jpa
  • spring-boot-starter-websocket – websocket uygulaması geliştirme
  • spring-boot-starter-thymeleaf – thymeleaf template-engine kullanımı

NOT: Birçok paket (spring-boot-starter-websocket) yine spring-boot-starter ön ekiyle başlayan paketleri (spring-boot-starter-web gibi) kullanır.

NOT: Spring Boot projelerinde sadece Spring Boot tarafından sağlanan paketlerin kullanım zorunluluğu yoktur diğer kütüphane ve paketlerde kullanılabilir.

dependencyManagement

Maven sadece bir tane parent pom kullanmayı sağlar.

Farklı bir parent pom kullanıldığında veya kullanılmak istendiğinde dependencyManagement özelliği kullanılarak benzer sonuç elde edilebilir.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.2.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

NOT: Bazı özellikler dependencyManagement tarafından desteklenmez.

Maven/Spring araçları

Paketleme, çalıştırma ve konteyner imajı oluşturma gibi işlemleri spring-boot-maven-plugin eklentisi sağlar.

Aşağıdaki komut ile eklenti işlemleri ve açıklamaları listelenebilir.

mvn spring-boot:help

Eklentiye ait komut ve açıklamaları aşağıdaki gibidir.

  • spring-boot:run – uygulamayı çalıştırır.
  • spring-boot:start – uygulamayı başlatır (test ile).
  • spring-boot:stop – çalışan uygulamayı durdurur.
  • spring-boot:repackage – uygulamayı paketler.
  • spring-boot:build-info – build-info.properties dosyasını oluşturur.
  • spring-boot:build-image – konteyner imajı oluşturur.
  • spring-boot:help – komut ve açıklamasını listeler.

NOT: Eklenti kullanarak işlemlerin yapılması ek özelliklerin kullanımını sağlayarak çeşitli hataların önüne geçecektir.

Merhaba Spring Boot

Spring Boot nasıl çalışır, kullanımı gibi bölümlerin daha iyi anlaşılması için basit web tabanlı bir uygulama hazırlayalım.

Spring Initializr, IDE veya Spring Boot CLI kullanarak web tabanlı proje oluşturalım.

spring init --dependencies=web MerhabaSpringBoot

Projedeki main metodunun olduğu sınıfı aşağıdaki gibi düzenleyelim.

@RestController
@SpringBootApplication
public class DemoApplication {

    @GetMapping("/merhaba")
    public String merhabaSpringBoot() {
        return "Merhaba Spring Boot!";
    }

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

}

NOT: Sınıf adı proje oluşturma yöntemine göre farklılık gösterebilir.

Projeyi IDE üzerinden veya proje dizininde komut yorumlayıcısına aşağıdaki komut satırını yazarak çalıştıralım.

mvn -q spring-boot:run

Tarayıcı ile aşağıdaki adrese giderek sonuca bakabiliriz.

http://localhost:8080/merhaba

Projeyi paketleyip çalıştırmak için sırasıyla aşağıdaki komutlar çalıştırılabilir.

mvn -q clean package
cd target
java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

Çeşitli araçlar kullanılarak sonuç görüntülenebilir.

curl --verbose http://localhost:8080/merhaba

Spring Boot herhangi bir Web Server, Servlet Container veya Application Server ayarına ihtiyaç duymadan geliştirilen uygulama türüne göre arka tarafta ayarları varsayılan-otomatik olarak yaparak uygulamanın çalışmasını sağladı.

Spring Boot nasıl çalışır

Yukarıdaki Merhaba Spring Boot örneği ve birçok örnekte olduğu gibi Spring Boot uygulamaları SpringApplication sınıfında yer alan statik run metoduna aktarılan başlangıç sınıfı ve komut argümanı ile başlatır.

Metot SpringApplication sınıfının bir örneğini oluşturup sınıf içerisinde yer alan run metodu ile uygulamayı başlatır.

Sınıf örneği oluşturulduğunda aşağıdaki işlemler yapılır.

  1. Başlangıç sınıfı primarySources özelliğine atanır,
  2. Projede yer alan sınıflara(bağımlılıklara) göre webApplicationType özelliği belirlenerek değer atanır,
  3. Proje paketlerindeki(spring-boot-autoconfigure-A.B.C.jar, spring-boot-A.B.C.jar vb.) META-INF/spring.factories dosyasında yer alan
    1. ApplicationContextInitializer arayüzünü uygulayan sınıflar initializers özelliğine atanır,
    2. ApplicationListener arayüzünü uygulayan sınıflar listeners özelliğine atanır,
  4. Java uygulamalarının başlangıcı olan main metodu mainApplicationClass özelliğine atanır.

NOT: Sürüme göre işlemler değişiklik gösterebilir.

Uygulamanın başlatıldığı run metodunda aşağıdaki işlemler yapılır.

  1. Uygulama başlatma süresini ölçen Startup sınıfının örneğini oluşturan create metodu çalıştırılır,
  2. Uygulama başlatılma adımlarında çalıştırılacak metotların belirlendiği SpringApplicationRunListeners sınıfı oluşturulur,
  3. Argüman listesi ApplicationArguments arayüzününü uygulayan sınıfa atanır,
  4. Ayarlar(environment, argümanlar, profile, properties vb.) uygulama türüne göre belirlenir,
  5. Ayarlara göre SpringApplicationBannerPrinter sınıfı kullanılarak banner yazdırılır,
    1. Herhangi bir banner ayarı belirtilmediğinde banner.txt dosyasını arar,
    2. Belirtilen dosyalar bulunmadığında varsayılan olarak SpringBootBanner sınıfı kullanılır,
  6. Uygulama türüne göre ConfigurableApplicationContext arayüzünü uygulayan sınıf oluşturulur,
  7. Belirlenen ayarlar(environment, listeners), argümanlar(ApplicationArguments) ve banner değerleri ConfigurableApplicationContext arayüzünü uygulayan sınıfa atanır,
    1. ConfigurableApplicationContext arayüzündeki refresh metodu belirlenen ayarlara göre sınıfları örneklendirilerek uygulamayı başlatılır,
  8. Başlatma süresini ölçen Startup sınıfının started metodu çalıştırılarak, uygulama ayarına göre başlangıç süresi yazdırılır,
  9. Uygulama başlatıldıktan sonra tanımlı ApplicationRunner ve CommandLineRunner arayüzünü uygulayan sınıflar çalıştırılır,
  10. SpringApplication sınıfındaki run metodu ConfigurableApplicationContext arayüzünü uygulayan sınıfı geri döndürür.

Metot sonucu döndürülen ConfigurableApplicationContext arayüzüne ait sınıf kullanılarak uygulama hakkında bilgi alınabilir.

ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
System.out.println("Nesne sayısı: " + context.getBeanDefinitionCount());
Arrays.stream(context.getBeanDefinitionNames())
        .forEach(System.out::println);

NOT: Tüm işlemler(varsayılan -otomatik ayarlar, ayar belirleme vb.) refresh metodunda yapılır.

@SpringBootApplication

@SpringBootApplication ifadesi @EnableAutoConfiguration, @ComponentScan ve @SpringBootConfiguration(@Configuration) ifadelerinin birleşimidir.

@SpringBootConfiguration ifadesi @Configuration ifadesini kullanarak sınıfın bir bean sınıfı olduğunu belirtir.

@ComponentScan ifadesine parametre verilmeyip varsayılan olarak kullanıldığında sınıfa ait paketinin altındaki bean sınıflarını tarar ve kayıt eder.

Bu nedenle @SpringBootApplication ifadesi kök paketteki sınıfta kullanılır.

@EnableAutoConfiguration

Spring Boot projesinin temelini oluşturan varsayılan-otomatik ayarların yapılmasını sağlar.

İfadenin tanımı aşağıdaki gibidir.

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

İfade ile kullanılan @AutoConfigurationPackage ifadesinin tanımı aşağıdaki gibidir.

@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}

İfade @Import ifadesi ile kullanılan AutoConfigurationPackages.Registrar sınıfı ile daha sonra kullanmak üzere bazı sınıfları(JPA sınıfları gibi) kayıt eder.

@EnableAutoConfiguration ifadesinde yer alan ve @Import ifadesi ile kullanılan AutoConfigurationImportSelector sınıfı META-INF/spring.factories dosyasındaki EnableAutoConfiguration ile belirtilen sınıfları yükler.

NOT: varsayılan-otomatik ayarların yer aldığı sınıflar spring-boot-autoconfigure modülünde yer alır.

Spring Boot kullanılarak geliştirilen web tabanlı uygulamalarda Tomcat ayarlarının nasıl yapıldığına ve çalıştırıldığına bakalım.

Web uygulaması geliştirmek için ilk olarak spring-boot-starter ile başlayan spring-boot-starter-web paketi projeye dahil edilir.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Paket ile birlikte web uygulaması oluşturmak ve yayınlamak için gerekli paketler(spring-web, tomcat-embed vb.) projeye dahil edilir.

Otomatik ayar sınıflarının yer aldığı META-INF/spring.factories dosyasındaki EnableAutoConfiguration ile belirtilen bean sınıfları sırasıyla çalıştırılır.

NOT: Projeye META-INF/spring.factories dosyası oluşturarak yükleme işlemi dinamik hale getirilebilir.

Örneğin; web sunucu ayarlarını yapmak için aşağıda tanımı olan ServletWebServerFactoryAutoConfiguration sınıfı kullanılır.

@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {}

Sınıf diğer bean sınıflarından farklı olarak koşullu bean tanımında kullanılan @Conditional ile başlayan ifadelere sahiptir.

@ConditionalOnClass ifadesi parametre olarak gönderilen sınıfın proje içerisinde olduğu durumda bean sınıfının tanımlanacağını belirtir.

NOT: spring-boot-autoconfigure modülündeki condition paketinde Java sürümü, Cloud sağlayıcı, JNDI gibi koşullu bean tanımlamak için ifadeler yer alır.

Bean sınıfının tanımlanması için gerekli olan koşul sağlanırsa @Import ifadesi ile belirtilen web sunucu sınıfları tanımlanır.

Web uygulamalarında varsayılan olarak Tomcat paketi kullanıldığı için aşağıda tanımı olan ServletWebServerFactoryConfiguration.EmbeddedTomcat sınıfı çalıştırılır.

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {}

Sınıf @Conditional ile başlayan koşullar sağlandığında, sınıf içerisinde yer alan metot ile TomcatServletWebServerFactory sınıfını kullanarak Tomcat sunucusunu yapılandırır.

Tomcat hakkında detaylı bilgi almak için Tomcat yazıma bakmalısın.

NOT: Varsayılan olarak gelen Tomcat devre dışı bırakılıp yerine Jetty veya Undertow kullanıldığında Tomcat sınıfı koşulları sağlamayacağından koşulu sağlayan sınıf çalışacaktır.

Web tabanlı uygulamalarda olduğu gibi diğer Spring Boot temelli uygulamalar varsayılan-otomatik ayar özelliğini kullanarak çalışır.

NOT: Varsayılan-otomatik ayar özelliği uygulamaların başlatıldığı ConfigurableApplicationContext#refresh ile başlatılır.

Hangi varsayılan-otomatik ayarların sağlandığı hangilerinin sağlanmadığı ile ilgili bilgi almak için Spring Boot uygulamasını aşağıdaki gibi çalıştırmak yeterli olacaktır.

SpringApplication.run(DemoApplication.class, new String[]{"--debug"});

NOT: Hata ayıklamayı aktif etmenin birden fazla yöntemi(ayar belirleme adımında yer aldığı gibi) vardır.

Spring Boot kullanımı

Spring Boot birçok varsayılan-otomatik ayar belirleme özelliğini içeren pakete sahiptir.

Geliştirilecek olan uygulama türüne göre paketlerin kullanımı farklıdır ve ayrıca uygulama türüne göre öğrenilmesi gerekir.

Aşağıda her Spring Boot uygulamasında kullanılabilecek Spring Boot kullanımı ile ilgili bilgiler yer almaktadır.

Uygulamayı başlatmak

Spring Boot uygulamalarını başlatmanın diğer bir yolu SpringApplication sınıf örneğini oluşturmaktır.

public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(DemoApplication.class);
    springApplication.run(args);
}

SpringApplication sınıfını doğrudan kullanmak varsayılan-otomatik olarak gelen bazı değerleri değiştirmeyi sağlar.

Başlangıç loglamasını kapatmak

springApplication.setLogStartupInfo(false);

Banner devre dışı bırakmak

springApplication.setBannerMode(Banner.Mode.OFF);

Özel banner belirleme

public static void main(String[] args) throws MalformedURLException {
    SpringApplication springApplication = new SpringApplication(DemoApplication.class);
    UrlResource urlResource = new UrlResource("https://www.yusufsezer.com.tr/yusuf-sezer.jpg");
    springApplication.setBanner(new ImageBanner(urlResource));
    springApplication.run(args);
}

NOT: Spring Boot 3 ile birlikte ImageBanner sınıfı kaldırılmıştır.

Özel Banner hazırlamak

springApplication.setBanner(new Banner() {
    @Override
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
        out.println("Yusuf Sezer");
    }
});

Arayüz tek metot tanımına sahip olduğundan Java 8 ile birlikte gelen lambda ifadesi olarak kullanılabilir.

springApplication.setBanner((Environment environment, Class<?> sourceClass, PrintStream out) -> {
    out.println("Yusuf Sezer");
});

Ayarları belirleme

SpringApplication sınıfında yer alan setDefaultProperties metotları kullanılarak ayarlar belirlenebilir.

Properties properties = new Properties();
properties.setProperty("spring.main.log-startup-info", "false");
properties.setProperty("spring.main.banner-mode", "off");
springApplication.setDefaultProperties(properties);

NOT: Spring Boot geniş ayar belirleme yöntemi sağlar.

Ayar belirleme ve kullanımı

Spring Boot sağladığı geniş ayar belirleme özelliği sayesinde geliştirilen uygulama türüne göre ayar belirleme ve kullanma imkanı sağlar.

Spring Boot ayarları JVM ayarları ile belirlenebilir.

@SpringBootApplication
public class DemoApplication {

    static {
        System.setProperty("spring.main.log-startup-info", "false");
        System.setProperty("spring.main.banner-mode", "off");
    }

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(DemoApplication.class);
        springApplication.run(args);
    }

}

JVM ayarları JAR dosyalarında aşağıdaki gibi belirlenebilir.

İlk olarak proje paketlenir.

mvn clean package
cd target

JVM değeri -D parametresi ile belirlenebilir.

java -Dspring.main.log-startup-info=false -Dspring.main.banner-mode=off -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

JVM değeri Spring Boot ile aşağıdaki gibi belirlenebilir.

mvn -q -Dspring-boot.run.jvmArguments="-Dspring.main.log-startup-info=false -Dspring.main.banner-mode=off" spring-boot:run

NOT: Belirlenen ayar tırnak işaretlerini(“,’) içeriyorsa kaçış karakteri kullanılmalıdır.

Uygulama ayarlarını komut yorumlayıcısı argümanında belirlemek için aşağıdaki komut kullanılır.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --spring.main.log-startup-info=false --spring.main.banner-mode=off

Komut yorumlayıcısında belirlenen ayarları Spring Boot ile belirlemek için aşağıdaki gibi kullanılabilir.

mvn -q -Dspring-boot.run.arguments="--spring.main.log-startup-info=false --spring.main.banner-mode=off" spring-boot:run

NOT: Spring Boot 1.x sürümlerinde ön ek(spring-boot) olmadan kullanılmalıdır.

Spring Boot işletim sistemi ortam değişkenlerine atanan değerleri kullanabilir.

Ayarlar işletim sistemine göre belirlenir.

SET spring.main.log-startup-info=false
SET spring.main.banner-mode=off

Uygulama çalıştırılır.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

NOT: Bazı işletim sistemleri tabanlı nokta(.) içeren ortam değişkeni tanımlamaya imkan vermez.

NOT: Nokta yerine alt çizgi(spring_main_banner_mode, spring_main_log_startup_info) kullanılabilir.

Ayar belirlemenin diğer bir yolu ise JSON kullanımıdır.

JVM ayarı olarak kullanımı aşağıdaki gibidir.

java -Dspring.application.json="{'spring':{'main':{'log-startup-info':'false','banner-mode':'off'}}}" -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

Komut yorumlayıcısı argümanı olarak kullanımı aşağıdaki gibidir.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --spring.application.json="{'spring':{'main':{'log-startup-info':'false','banner-mode':'off'}}}"

İşletim sistemi ortam değişkeni olarak kullanımı aşağıdaki gibidir.

SET SPRING_APPLICATION_JSON={'spring':{'main':{'log-startup-info':'false','banner-mode':'off'}}}
export SPRING_APPLICATION_JSON="{'spring':{'main':{'log-startup-info':'false','banner-mode':'off'}}}"

NOT: Ortam değişkeni tanımlaması işletim sistemine göre farklılık gösterir.

Spring Boot sağladığı geniş ve esnek ayar belirleme özelliği sayesinde ihtiyaç halinde farklı ayar belirleme yönteminin kullanımını sağlar.

Kullanılan ayar sayısı arttıkça ortam değişkenleri ve komut yorumlayıcısı üzerinden ayarların belirlenmesi zorlaşacaktır.

Bundan dolayı application.properties veya application.yml dosyalarının kullanımı faydalı olacaktır.

Yukarıdaki ayarların application.properties dosyasında kullanımı aşağıdaki gibidir.

src/main/resources/application.properties

spring.main.log-startup-info=false
spring.main.banner-mode=off

Yukarıdaki ayarların application.yml dosyasında kullanımı aşağıdaki gibidir.

src/main/resources/application.yml

spring:
    main:
        log-startup-info: false
        banner-mode: off

Özel ayar tanımlama

Spring Boot özel ayar tanımlamayı ve uygulamada kullanmayı sağlar.

Ayar tanımlama

src/main/resources/application.properties

app.name=Merhaba Spring Boot

veya

src/main/resources/application.yml

app:
    name: Merhaba Spring Boot

ile yapılabilir.

Tanımlanan ayara @Value ifadesi ile aşağıdaki gibi erişilir.

@SpringBootApplication
public class DemoApplication {

    @Value("${app.name}")
    public String appName;

    @PostConstruct
    public void init() {
        System.out.println(appName);
    }

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

}

NOT: Komut argümanı, JVM ve ortam değişkeni ile özel ayar belirlenebilir.

Bir ayar içerisinde başka bir ayar aşağıdaki gibi kullanılabilir.

src/main/resources/application.properties

app.name=Merhaba Spring Boot!
app.description=${app.name} Spring Boot ile hazırlanmıştır.

src/main/resources/application.yml

app:
    name: Merhaba Spring Boot
    description: ${app.name} Spring Boot ile hazırlanmıştır.

Ayara erişim sağlanır.

@SpringBootApplication
public class DemoApplication {

    @Value("${app.description}")
    public String appDescription;

    @PostConstruct
    public void init() {
        System.out.println(appDescription);
    }

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

}

Maven ile tanımlanan ayarlar aşağıdaki gibi kullanılabilir.

src/main/resources/application.properties

app.description=@project.name@ Spring Boot ile hazırlanmıştır.

src/main/resources/application.yml

app:
    description: @project.name@ Spring Boot ile hazırlanmıştır.

Maven dosyasındaki project etiketi altındaki ayarlara @project.ayar@ properties etiketi alanındaki ayarlara @ayar@ ile erişim sağlanır.

Özel ayar tanımlaması yapılmadığında varsayılan değer aşağıdaki gibi belirlenebilir.

@Value("${app.name : Merhaba Spring Boot!}")

Sınıf içindeki birden fazla ayara @Value ifadesi ile erişmek zaman alacaktır.

app.name=@project.name@
app.description=@project.description@

Spring Boot sağladığı @ConfigurationProperties ifadesi ile birden fazla ayarı bağlama, iç içe bağlama, doğrulama gibi işlemleri yapmayı sağlar.

@SpringBootApplication
@ConfigurationProperties("app")
public class DemoApplication {

    public String name;
    public String description;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @PostConstruct
    public void init() {
        System.out.println(name);
        System.out.println(description);
    }

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

}

NOT: İfadenin çalışması için getter-setter metotları tanımlı olmalıdır.

İfade farklı türden verileri bağlayabilir.

yusuf.id=1
yusuf.firstName=Yusuf
yusuf.last-name=Sezer
yusuf.languages[0]=Java
yusuf.languages[1]=JavaScript
yusuf.features.middleName=Sefa

Tanımlı ayarların kullanımı aşağıdaki gibidir.

@SpringBootApplication
public class DemoApplication {

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

    @ConfigurationProperties("yusuf")
    @Component
    class Person {

        Long id;
        String firstName;
        String lastName;
        List<String> languages;
        Map<String, String> features;

        @PostConstruct
        public void init() {
            System.out.println(this);
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public List<String> getLanguages() {
            return languages;
        }

        public void setLanguages(List<String> languages) {
            this.languages = languages;
        }

        public Map<String, String> getFeatures() {
            return features;
        }

        public void setFeatures(Map<String, String> features) {
            this.features = features;
        }

        @Override
        public String toString() {
            return "Person{" + "id=" + id
                    + ", firstName=" + firstName
                    + ", lastName=" + lastName
                    + ", languages=" + languages
                    + ", features=" + features
                    + '}';
        }

    }

}

İfadeyi kullanan sınıf @EnableConfigurationProperties ifadesi ile belirtildiğinde @Component veya @Bean ifadeleri kullanılmayabilir.

@EnableConfigurationProperties(DemoApplication.Person.class)
public class DemoApplication {

    // diğer kodlar

    @ConfigurationProperties("yusuf")
    class Person {
        // tanımlar
	}
	
}

NOT: Ayar tanımı tüm ayar tanımlarında geçerli olduğu gibi first-name, first_name ve firstName aynı ayarı belirtir.

NOT: Ayar tanımında büyük küçük harf (first_name, FIRST_NAME, FIRST_nAME) duyarsızdır.

NOT: Karışıklığın önüne geçmek için Java adlandırma kurallarını takip etmek faydalı olacaktır.

Sınıflara değer ataması @Bean ifadesi ile birlikte yapılabilir.

@SpringBootApplication
public class DemoApplication {

    @Bean
    @ConfigurationProperties("yusuf")
    public Person yusuf() {
        return new Person();
    }

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

    class Person {

        Long id;
        String firstName;
        String lastName;
        List<String> languages;
        Map<String, String> features;

        @PostConstruct
        public void init() {
            System.out.println(this);
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public List<String> getLanguages() {
            return languages;
        }

        public void setLanguages(List<String> languages) {
            this.languages = languages;
        }

        public Map<String, String> getFeatures() {
            return features;
        }

        public void setFeatures(Map<String, String> features) {
            this.features = features;
        }

        @Override
        public String toString() {
            return "Person{" + "id=" + id
                    + ", firstName=" + firstName
                    + ", lastName=" + lastName
                    + ", languages=" + languages
                    + ", features=" + features
                    + '}';
        }

    }

}

Bu özellik sayesinde farklı ayar tanımı yapılabilir.

@Bean
@ConfigurationProperties("yusuf") // yusuf ile başlayan ayarları kullan
public Person yusuf() {
    return new Person();
}

@Bean
@ConfigurationProperties("ramazan") // ramazan ile başlayan ayarları kullan
public Person ramazan() {
    return new Person();
}

Sınıf içerisinde kullanılan diğer sınıflara değer ataması yapılabilir.

@SpringBootApplication
@EnableConfigurationProperties(DemoApplication.Person.class)
public class DemoApplication {

    static class Other {

        List<String> languages;
        Map<String, String> features;

        public List<String> getLanguages() {
            return languages;
        }

        public void setLanguages(List<String> languages) {
            this.languages = languages;
        }

        public Map<String, String> getFeatures() {
            return features;
        }

        public void setFeatures(Map<String, String> features) {
            this.features = features;
        }

        @Override
        public String toString() {
            return "Other{" + "languages=" + languages
                    + ", features=" + features
                    + '}';
        }

    }

    @ConfigurationProperties("yusuf")
    static class Person {

        Long id;
        String firstName;
        String lastName;
        Other other;

        @PostConstruct
        public void init() {
            System.out.println(this);
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public Other getOther() {
            return other;
        }

        public void setOther(Other other) {
            this.other = other;
        }

        @Override
        public String toString() {
            return "Person{" + "id=" + id
                    + ", firstName=" + firstName
                    + ", lastName=" + lastName
                    + ", other=" + other
                    + '}';
        }

    }

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

}

@ConfigurationProperties ve @Value ifadeleri ayarları belirtilen sınıf türüne çevirmede DataBinder, Converter özelliklerini kullanılır.

@ConfigurationProperties tür dönüşüm özelliğini @ConfigurationPropertiesBinding ile sağlar.

Aşağıda yer alan ifade LocalDate türüne dönüştürme sırasında hata verecektir.

yusuf.birthDate=01-01-1453

Tür dönüşümü için Converter arayüzünün aşağıdaki gibi uygulanması yeterli olacaktır.

@SpringBootApplication
@EnableConfigurationProperties(DemoApplication.Person.class)
public class DemoApplication {

    @Component
    @ConfigurationPropertiesBinding
    class LocalDateConverter implements Converter<String, LocalDate> {

        @Override
        public LocalDate convert(String dateText) {
            if (dateText == null) {
                return null;
            }
            return LocalDate.parse(dateText, DateTimeFormatter.ofPattern("MM-dd-yyyy"));
        }
    }

    @ConfigurationProperties("yusuf")
    static class Person {

        LocalDate birthDate;

        public LocalDate getBirthDate() {
            return birthDate;
        }

        public void setBirthDate(LocalDate birthDate) {
            this.birthDate = birthDate;
        }

        @PostConstruct
        public void init() {
            System.out.println(birthDate);
        }

    }

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

}

Ayarın dönüşümü sırasında LocalDateConverter sınıfı çalıştırılarak dönüşüm işlemi yapılacaktır.

@ConfigurationProperties ifadesi JEE paketinde yer alan Bean Validation şartnamesini ile ayar doğrulama-kontrol işlemini yapmayı sağlar.

yusuf.mail=yusufsezer[@]mail.com

Özelliğin kullanımı için ilk olarak gerekli bağımlılığın projeye eklenmesi gerekir.

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

Ayarların kullanılacağı sınıfta Bean Validation ifadeleri kullanılarak doğrulama-kontrol işlemi yapılır.

@SpringBootApplication
@EnableConfigurationProperties(DemoApplication.Person.class)
public class DemoApplication {

    @ConfigurationProperties("yusuf")
    @Validated
    static class Person {

        @Email
        String mail;

        @PostConstruct
        public void init() {
            System.out.println(this);
        }

        public String getMail() {
            return mail;
        }

        public void setMail(String mail) {
            this.mail = mail;
        }

        @Override
        public String toString() {
            return "Person{" + "mail=" + mail + '}';
        }

    }

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

}

NOT: @Valid ifadesi yerine @Validated kullanılmalıdır.

Spring Boot sağladığı dinamik ayar belirleme özelliği ve kullanımı yanında yardımcı ayar belirleme sınıflarını sağlar.

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        ConfigurableEnvironment environment = context.getEnvironment();
        System.out.println(environment);
    }

}

RandomValuePropertySource ile rastgele değer belirlemeyi sağlar.

@SpringBootApplication
public class DemoApplication {

    @Value("${random.int}")
    Integer randomInteger;

    @Value("${random.int(100)}")
    int randomInt;

    @Value("${random.int(100,200)}")
    int randomRange;

    @Value("${random.long}")
    Long randomLong;

    @Value("${random.long(3000000)}")
    long randomLong2;
    
    @Value("${random.long[100,70000000000000000]}")
    Long randomLongRange;

    @Value("${random.value}")
    String randomByte;

    @Value("${random.uuid}")
    UUID randomUuid;

    @PostConstruct
    public void init() {
        System.out.println("randomInteger: " + randomInteger);
        System.out.println("randomInt: " + randomInt);
        System.out.println("randomRange: " + randomRange);
        System.out.println("randomLong: " + randomLong);
        System.out.println("randomLong2: " + randomLong2);
        System.out.println("randomLongRange: " + randomLongRange);
        System.out.println("randomByte: " + randomByte);
        System.out.println("randomUuid: " + randomUuid);
    }

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

}

NOT: Rastgele değer özelliği ayar dosyalarında(properties, yml) kullanılabilir.

Geliştirme araçları

Her değişiklik sonrası uygulamanın yeniden başlatılması, tarayıcının yenilenmesi işlemlerini otomatik olarak yapmak için DevTools paketini eklemek yeterli olacaktır.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

Her değişiklik sonrası uygulama otomatik olarak yeniden başlatılacaktır.

NOT: Uygulamanın otomatik olarak yeniden başlatılması işlemi sadece uygulama geliştirme sırasında çalışacaktır.

Paket tarayıcılara yüklenen LiveReload eklentisi ile birlikte çalışarak yapılan değişiklik sonrası sayfayı yeniler.

Proje dizini haricindeki dosyalar aşağıdaki ayar ile takip edilebilir.

spring.devtools.restart.additional-paths=.

Belirli bir dosyadaki değişiklik aşağıdaki ayar ile takip edilebilir.

spring.devtools.restart.trigger-file=YusufSezer.java

Aşağıdaki ayar ile istenilen dosya ve dizinlerin takibi devre dışı bırakılabilir.

spring.devtools.restart.exclude=static/**,public/**

NOT: Ayar Spring Boot tarafından varsayılan-otomatik değerlere sahiptir.

Devre dışı bırakılan dosya ve dizinlere aşağıdaki ayar ile ekleme yapılabilir.

spring.devtools.restart.additional-exclude=yusuf/**

Değişiklik ve değişiklik süresi aşağıdaki ayar ile düzenlenebilir.

spring.devtools.restart.poll-interval=1000
spring.devtools.restart.quiet-period=400

Eklenti ayrıca uzak sunucudaki uygulamanın dinamik olarak yenilenmesini sağlar.

Uzak sunucuda yayınlanacak uygulamada DevTools paketinin aktif olması sağlanır.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

Uzak sunucu iletişimi sırasında kullanılacak gizli anahtar/şifre belirlenir.

spring.devtools.remote.secret=yusufsezer

Uygulama uzak sunucuda yayınlanır.

Geliştirme ortamında aşağıdaki başlangıç sınıfı ve uzak sunucu adresi ile çalıştırılır.

org.springframework.boot.devtools.RemoteSpringApplication https://uzak-sunucu-adresi 

NOT: Özelliğin kullanımı sırasında http yerine https kullanımı özel şifre ile belirtilen bilginin ele geçirilmemesi için faydalı olacaktır.

Yardımcı sınıflar

Spring Boot çeşitli bilgilerin alınması, komutların çalıştırılması işlemlerini yapmak için çeşitli yardımcı sınıflara sahiptir.

Komut argümanlarını almak

Komut satırına yazılan parametrelere erişmek için ApplicationArguments arayüzü kullanılır.

@SpringBootApplication
public class DemoApplication {

    @Autowired
    ApplicationArguments applicationArguments;

    @PostConstruct
    public void init() {
        applicationArguments.getNonOptionArgs()
                .forEach(System.out::println);

    }

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

}
java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar -firstName=yusuf -lastName=sezer

NOT: Komut argümanlarına @Value ifadesi kullanılarak erişilebilir.

Başlangıçta komutların çalıştırılması

Uygulama başlangıcında örnek verilerin yüklenmesi, bir web sayfasına istek göndermek gibi işlemleri yapmak için CommandLineRunner veya ApplicationRunner arayüzünü uygulayan bean sınıfının tanımlanması yeterli olacaktır.

@SpringBootApplication
public class DemoApplication {

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

    @Component
    class WriteDate implements CommandLineRunner {

        @Override
        public void run(String... args) throws Exception {
            System.out.println(LocalDate.now());
        }

    }

    @Component
    class WriteTime implements ApplicationRunner {

        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println(LocalTime.now());
        }

    }

}

Arayüzler tek metoda sahip olduğundan Java 8 ile birlikte gelen lambda ifadesi olarak kullanılabilir.

Arayüzleri uygulayan birden fazla sınıf tanımlandığında sıralama @Order ifadesi ile belirlenebilir.

NOT: Arayüzler arasında sadece parametre farklılığı vardır.

Çıkış kodu üretmek

Uygulama sonucunda bir çıkış kodu üretmek için ExitCodeGenerator arayüzünü sağlar.

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        int exit = SpringApplication.exit(context);
        System.exit(exit);
    }

    @Component
    class MyExit implements ExitCodeGenerator {

        @Override
        public int getExitCode() {
            return -1;
        }

    }

}

Uygulamadan çıkış sırasında gerçekleşen ExitCodeEvent olayında aşağıdaki gibi işlem yapılabilir.

@SpringBootApplication
public class DemoApplication {

    @EventListener
    public void onExit(ExitCodeEvent exitCodeEvent) {
        ApplicationContext context = (ApplicationContext) exitCodeEvent.getSource();

        System.out.println("Tanımlı bean sınıfları");
        Arrays.stream(context.getBeanDefinitionNames())
                .forEach(System.out::println);

        String mesaj = String.format("Çıkış kodu: %s",
                exitCodeEvent.getExitCode());
        System.out.println(mesaj);
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        int exit = SpringApplication.exit(context);
        System.exit(exit);
    }

    @Component
    class MyExit implements ExitCodeGenerator {

        @Override
        public int getExitCode() {
            return -1;
        }

    }

}

Arayüz istisna sınıfları ile kullanıldığında SpringApplication.exit metoduna ihtiyaç duymadan aşağıdaki gibi kullanılabilir.

@SpringBootApplication
public class DemoApplication {

    @Bean
    ApplicationRunner init() {
        return args -> {
            throw new MyException("Merhaba Spring Boot!");
        };
    }

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

    class MyException
            extends RuntimeException
            implements ExitCodeGenerator {

        public MyException(String message) {
            super(message);
        }

        @Override
        public int getExitCode() {
            return 1453;
        }

    }

}

İstisna sınıfına göre çıkış kodu üretmek için ExitCodeExceptionMapper arayüzü kullanılabilir.

@SpringBootApplication
public class DemoApplication {

    @Bean
    ApplicationRunner init() {
        return args -> {
            throw new MyException("Merhaba Spring Boot!");
        };
    }

    @Bean
    ExitCodeExceptionMapper mapper() {
        return exception -> {
            if (exception.getCause() instanceof MyException) {
                return 1453;
            }
            return 0;
        };
    }

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

    class MyException
            extends RuntimeException {

        public MyException(String message) {
            super(message);
        }

    }

}

NOT: Arayüz ExitCodeGenerator arayüzünün kullanılamadığı önceden tanımlı istisna sınıfına göre çıkış kodu üretiminde faydalı olacaktır.

Spring Boot sürümünü öğrenme

SpringBootVersion sınıfındaki getVersion metodu kullanılarak Spring Boot sürümüne ulaşılabilir.

@SpringBootApplication
public class DemoApplication {

    @PostConstruct
    void init() {
        String version = SpringBootVersion.getVersion();
        System.out.println(version);
    }

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

}

NOT: Spring Boot sürümüne göre uygulama geliştirirken sürüm kontrolü yapmak faydalı olacaktır.

Uygulama profili

Spring Boot geliştirme, test veya yayınlama adımında farklı ortam ve ayarları belirlemeyi geniş bir şekilde sağlar.

Profile özgü işlemler @Profile ifadesi ile belirlenebilir.

@SpringBootApplication
public class DemoApplication {

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

    @Component
    @Profile("test")
    class TestBean {

        @PostConstruct
        public void init() {
            System.out.println("com.yusufsezer.DemoApplication.TestBean.init()");
        }

    }

    @Component
    @Profile("production")
    class ProdBean {

        @PostConstruct
        public void init() {
            System.out.println("com.yusufsezer.DemoApplication.ProdBean.init()");
        }

    }

}

Profil belirlendikten sonra ayar belirleme yöntemleri ile profilin aktif edilmesi gerekir.

Komut argümanı kullanarak

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --spring.profiles.active=test

JVM kullanarak

java -Dspring.profiles.active=test -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

Ortam değişkeni kullanarak

set spring.profiles.active=production
export SPRING_PROFILES_ACTIVE=test

veya

export spring_profiles_active=test

Ayar dosyaları ile profil belirlenebilir.

src/main/resources/application.properties

spring.profiles.active=test

NOT: Profil değiştirilerek sonuç gözlemlenebilir.

Birden fazla profilin olduğu durumlarda belirlenen bazı profillerin her zaman aktif olması istenebilir.

Bu durumda spring.profiles.active ayarı aşağıdaki gibi belirlenebilir.

spring.profiles.active=profil1,profil2

Uygulama çalıştırıldığında profil1 ve profil2 ile belirtilen profiller her zaman aktif olacaktır.

Profile özgü ayar dosyaları

Spring Boot profile özgü ayar dosyaları kullanmayı destekler.

src/main/resources/application.properties

app.name=Merhaba Spring Boot!
app.description=Varsayılan açıklama.

src/main/resources/application-test.properties

app.description=Uygulama test ediliyor.

src/main/resources/application-production.properties

app.description=Uygulama yayımlandı.
@SpringBootApplication
public class DemoApplication {

    @Value("${app.name}")
    public String appName;

    @Value("${app.description}")
    public String appDescription;

    @PostConstruct
    public void init() {
        System.out.println(appName);
        System.out.println(appDescription);
    }

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

}

İstenilen profile göre uygulama çalıştırılır.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --spring.profiles.active=production

Belirlenen profile göre(production) profili özgü ayar dosyası(application-production.properties) kullanılacaktır.

NOT: Profile özgü ayar belirleme YML dosyalarında kullanılabilir.

Spring Boot profil özelliği Maven profil özelliği ile birlikte kullanılabilir.

Maven profilleri belirlenir.

<profiles>
    <profile>
        <id>test</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profiles.active>test</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>production</id>
        <properties>
            <spring.profiles.active>production</spring.profiles.active>
        </properties>
    </profile>
</profiles>

Belirlenen ayarlar Spring Boot ayar dosyasında kullanılarak Maven tarafından belirlenen profil Spring Boot içinde kullanılır.

src/main/resources/application.properties

spring.profiles.active=@spring.profiles.active@
app.name=Merhaba Spring Boot!
app.description=Varsayılan açıklama.

Maven profili belirlenerek Spring Boot ile birlikte çalışması sağlanır.

mvn -P production spring-boot:run

veya

mvn -P production clean package
java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar

Spring Boot profil özelliği Maven profil özelliği ile birlikte kullanılarak Maven ile profile özgü bağımlılık belirlenebilir.

Böylece test ortamında kullanılan In-Memory veritabanı bağımlılığı(h2, hsql vb.), uygulama yayınlama adımında pakete(jar,war,ear) dahil edilmeyebilir.

NOT: Profile göre ayar belirleme ile geliştirme, test veya uygulama yayınlama adımında farklı kaynakların kullanımı sağlanır.

Loglama

Spring Boot loglama karmaşıklığını SLF4J kullanarak giderir.

SLF4J loglama kütüphaneleri(Apache Commons Logging, Log4J, Java Util Logging, Logback) için arayüz görevi görerek birlikte çalışabilirliği sağlar.

Spring Boot varsayılan olarak Logback loglama kütüphanesi kullanılır.

Loglama işlemi Java içerisinde yer alan Java Util Logging ile aşağıdaki gibi yapılabilir.

@SpringBootApplication
public class DemoApplication {

    private static final Logger LOG = Logger.getLogger(DemoApplication.class.getName());

    @PostConstruct
    public void init() {
        LOG.info("Merhaba Spring Boot!");
    }

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

}

Loglama işlemi SLF4J ile aşağıdaki gibi yapılabilir.

@SpringBootApplication
public class DemoApplication {

    private static final Logger LOG = LoggerFactory.getLogger(DemoApplication.class.getName());

    @PostConstruct
    public void init() {
        LOG.info("Merhaba Spring Boot!");
    }

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

}

Varsayılan olarak kullanılan Logback kütüphanesi dosyasında değişiklik yapılarak loglama çıktısı düzenlenebilir.

src\main\resources\logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="stdout"/>
    </root>
</configuration>

Log4j2

Logback bağımlılığı devre dışı bırakılarak spring-boot-starter-log4j2 paketinin eklenmesi ile Log4j2 kütüphanesi kullanılır.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
</dependencies>

Kütüphane dosyası ile loglama çıktısı düzenlenir.

src\main\resources\log4j2-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

NOT: Kütüphaneye ait dokümantasyon incelenerek çıktı düzenlemesi yapılabilir.

Spring Boot komut yorumlayıcısı desteğine göre log çıktısını renklendirme özelliğine sahiptir.

Loglama çıktısındaki renklendirme spring.output.ansi.enabled ayarına always, detect veya never değeri verilerek düzenlenir.

Spring Boot sağladığı geniş loglama kütüphanesi desteğinin yanında ayar dosyaları ile log ayarlarını düzenlemeyi sağlar.

logging.config – Loglama kütüphanesine göre ayar dosyasını belirlemek için kullanılır.

logging.file.name / LOG_FILE – Log dosyasını belirtir.

logging.file.path / LOG_PATH – Log dosya yolunu belirtir.

logging.pattern.console / CONSOLE_LOG_PATTERN – Log çıktısını verir(konsol).

logging.pattern.file / FILE_LOG_PATTERN – Log çıktısını verir(dosya).

logging.level.xyz /LOGGING_LEVEL_X_Y_Z – xyz log türünü(TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF) belirtir.

src/main/resources/application.properties

#logging.config=log-ayarlari.xml
logging.config=classpath:logback-spring.xml
#logging.file.name=@project.name@.log
#logging.file.path=/var/log
#logging.pattern.console=%clr(%d{yy-MM-dd E HH:mm:ss.SSS}){blue} -- %m%n
#logging.pattern.file=%m%n
#logging.level.org.springframework.web=debug

NOT: Spring Boot varsayılan olarak DefaultLogbackConfiguration sınıfında yer alan ayarları kullanır.

Spring Boot Logback ile birlikte belirlenen profile göre loglama ayarını belirlemeyi sağlar.

src\main\resources\logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <springProfile name="dev">
                <pattern>%d{yy-MMMM-dd HH:mm:ss:SSS} %5p %t %c{2}:%L - %m%n</pattern>
            </springProfile>
            <springProfile name="prod">
                <pattern>%d{yy-MM-dd E HH:mm:ss.SSS} %5p %t %c{2}:%L - %m%n</pattern>
            </springProfile>
        </encoder>
    </appender>
    <springProfile name="dev">
        <root level="DEBUG">
            <appender-ref ref="stdout"/>
        </root>
    </springProfile>
    <springProfile name="production">
        <root level="INFO">
            <appender-ref ref="stdout"/>
        </root>
    </springProfile>
</configuration>

Profile göre loglama ayarları kullanılacaktır.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --spring.profiles.active=test

Loglama türünü belirlemek için ayrıca komut argümanı da kullanılabilir.

java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --debug
java -jar MerhabaSpringBoot-0.0.1-SNAPSHOT.jar --trace

Diğer

Spring Boot, Spring Framework ve çeşitli kütüphaneleri sağlamış olduğu varsayılan-otomatik ayar özelliği ile kullanarak hızlı uygulama geliştirmeyi sağlar.

Varsayılan-otomatik ayarlar geliştirilecek uygulama türüne ve kullanılan spring-boot-starter paketine göre farklılık gösterir.

Uygulama türüne göre sağladığı ServletRegistrationBean, FilterRegistrationBean, ServletListenerRegistrationBean gibi ek sınıflar ile uygulama türüne göre işlemleri dinamik ve esnek bir şekilde yapmayı sağlar.

Sağlamış olduğu çeşitli ayarlar ile hataların yönetilmesini, ayar belirleme ile değiştirilmesini, soyut sınıflar ve arayüzler kullanılarak düzenlenmesini sağlar.

Birçok paketinde Spring Framework ve Spring platformundaki paketleri(Spring Web MVC, Spring Data, Spring Security) kullandığından dolayı geliştirilen uygulama türüne göre Spring platformunda yer alan paket kullanımını öğrenmek faydalı olacaktır.

Son

Sağlamış olduğu kalıplaşmış veya best pratices varsayılan-otomatik ayarları belirleyerek Spring platformu ve Java kütüphaneleri ile kolay, hızlı uygulama geliştirmeyi sağlar.

Ancak bu ayarlar Spring Boot sürümlerine göre farklılık göstermektedir.

Bundan dolayı kullanılan Spring Boot sürümüne ve kütüphane desteğine bakmak faydalı olacaktır.

Uygulama geliştirirken JCP ve Jakarta/Java EE tarafından belirlenen standartları kullanmak platform değişikliği, beklenmedik değişikliklere karşı faydalı olacaktır.

Java Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.


Bunlarda ilgini çekebilir


LinkedIn grubuna buradan katılın.