[JAVA] J'ai essayé l'initialisation paresseuse avec Spring Boot 2.2.0

Spring Boot v2.2.0

Spring Boot v2.2.0 a été publié et est maintenant GA.

Examinons donc l'une de ses fonctions, l'initialisation paresseuse.

Spring Boot 2.2.0 Release v2.2.0.RELEASE · spring-projects/spring-boot · GitHub Spring Boot 2.2 Release Notes · spring-projects/spring-boot Wiki · GitHub Spring Boot Reference Documentation

environnement

Créer un projet

Le projet Hinagata est créé à partir de Spring Initializr.

spring-initializr.PNG

Gradle Nous avons confirmé que Gradle 5.6.2 s'applique aux projets Gradle créés avec Spring Initializr.

> gradlew -version

------------------------------------------------------------
Gradle 5.6.2
------------------------------------------------------------

Build time:   2019-09-05 16:13:54 UTC
Revision:     55a5e53d855db8fc7b0e494412fc624051a8e781

Kotlin:       1.3.41
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.14 compiled on March 12 2019
JVM:          13-ea (Oracle Corporation 13-ea+33)
OS:           Windows 10 10.0 amd64

Lazy Initialization

L'initialisation différée est utilisée pour générer des beans gérés par ApplicationContext lorsque le bean cible est appelé, et non au démarrage de l'application (≒ ApplicationContext est initialisé).

Ce mécanisme était disponible depuis les versions précédentes, mais à partir de la v2.2.0, l'initialisation différée sera appliquée uniformément en appliquant true à la propriétéspring.main.lazy-initialization.

spring:
  main:
    lazy-initialization: true
package jp.co.musako.domain.model;

public class LazyInitializationDemoBean {

    private String message;

    public LazyInitializationDemoBean(String message) {
        this.message = message;
        System.out.println("call constructor " + this.message);
    }

    public void writer(String message){
        System.out.println(this.message + " is " + message);
    }
}
package jp.co.musako.config;

import jp.co.musako.domain.model.LazyInitializationDemoBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Bean("lazyInitializationDemoBean1")
    public LazyInitializationDemoBean lazyInitializationDemoBean1(){
        return new LazyInitializationDemoBean("create lazyInitializationDemoBean1");
    }

    @Bean("lazyInitializationDemoBean2")
    public LazyInitializationDemoBean lazyInitializationDemoBean2(){
        return new LazyInitializationDemoBean("create lazyInitializationDemoBean2");
    }
}
package jp.co.musako;

import jp.co.musako.domain.model.LazyInitializationDemoBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
        System.out.println("Initialize Application Context");

        LazyInitializationDemoBean bean1 = ctx.getBean("lazyInitializationDemoBean1", LazyInitializationDemoBean.class);
        bean1.writer("first bean");

        LazyInitializationDemoBean bean2 = ctx.getBean("lazyInitializationDemoBean2", LazyInitializationDemoBean.class);
        bean2.writer("second bean");
    }
}

Résultat d'exécution

>gradlew bootRun

> Task :bootRun

2019-10-23 18:16:37.620  INFO 12708 --- [           main] jp.co.musako.Application                 : Started Application in 4.295 seconds (JVM running for 4.933)
Initialize Application Context
call constructor lazyInitializationDemoBean1
lazyInitializationDemoBean1 is first bean
call constructor lazyInitializationDemoBean2
lazyInitializationDemoBean2 is second bean

Ici, vous pouvez voir que le traitement est effectué dans l'ordre suivant.

  1. Démarrez l'application
  1. Génération de haricots --Output "appeler le constructeur lazyInitializationDemoBean1" dans le constructeur du bean
  2. La méthode d'écriture du bean généré est appelée

Exemption de l'initialisation paresseuse

Pour appliquer LazyInitialization à votre projet en définissant spring.main.lazy-initialization = true, vous pouvez exclure des beans spécifiques de LazyInitialization en:

  1. Définissez @ org.springframework.context.annotation.Lazy (false) sur Bean
  2. Enregistrez le bean cible dans ʻorg.springframework.boot.LazyInitializationExcludeFilter`
package jp.co.musako.config;

import jp.co.musako.domain.model.ExcludeLazyInitializationDemoBean;
import jp.co.musako.domain.model.LazyInitializationDemoBean;
import org.springframework.boot.LazyInitializationExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class Config {
    
    @Bean
    static LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() {
        return LazyInitializationExcludeFilter.forBeanTypes(ExcludeLazyInitializationDemoBean.class);
    }

    //Initialisation paresseuse applicable
    @Bean("lazyInitializationDemoBean1")
    public LazyInitializationDemoBean lazyInitializationDemoBean1(){
        return new LazyInitializationDemoBean("lazyInitializationDemoBean1");
    }

    //Non applicable à l'initialisation paresseuse
    @Bean("lazyInitializationDemoBean2")
    @Lazy(false)
    public LazyInitializationDemoBean lazyInitializationDemoBean2(){
        return new LazyInitializationDemoBean("lazyInitializationDemoBean2");
    }

    //Non applicable à l'initialisation paresseuse
    @Bean
    public ExcludeLazyInitializationDemoBean ExcludeLazyInitializationDemoBean(){
        return new ExcludeLazyInitializationDemoBean("excludeLazyInitializationDemoBean");
    }
}
package jp.co.musako;

import jp.co.musako.domain.model.ExcludeLazyInitializationDemoBean;
import jp.co.musako.domain.model.LazyInitializationDemoBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
        System.out.println("Initialize Application Context");

        LazyInitializationDemoBean bean1 = ctx.getBean("lazyInitializationDemoBean1", LazyInitializationDemoBean.class);
        bean1.writer("first bean");

        LazyInitializationDemoBean bean2 = ctx.getBean("lazyInitializationDemoBean2", LazyInitializationDemoBean.class);
        bean2.writer("second bean");

        ExcludeLazyInitializationDemoBean ExcludeLazyInitializationBean = ctx.getBean("ExcludeLazyInitializationDemoBean", ExcludeLazyInitializationDemoBean.class);
        ExcludeLazyInitializationBean.writer("third bean");
    }

}

>gradlew bootRun

> Task :bootRun

call constructor lazyInitializationDemoBean2
call constructor excludeLazyInitializationDemoBean
2019-10-23 18:52:52.464  INFO 6004 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-10-23 18:52:52.468  INFO 6004 --- [           main] jp.co.musako.Application                 : Started Application in 2.978 seconds (JVM running for 3.454)
Initialize Application Context
call constructor lazyInitializationDemoBean1
lazyInitializationDemoBean1 is first bean
lazyInitializationDemoBean2 is second bean
excludeLazyInitializationDemoBean is third bean

Comme mentionné ci-dessus, sur les trois beans définis dans Config.java, seul lazyInitializationDemoBean1 est la cible de LazyInitialization.

Cliquez ici pour le code source: GitHub --forests-k / spring-boot-lazy-initialization : Spring Boot v2.2.0 lazy-initialization sample

Éléments à prendre en compte lors de l'application de l'initialisation paresseuse

Les avantages de l'introduction de Lazy Intialization sont qu'elle accélère le démarrage de l'application et qu'elle ne gaspille pas de mémoire car elle s'initialise en cas de besoin.

Cependant, l'initialisation du haricot et le maintien du haricot dans le conteneur si nécessaire modifie le cycle de vie du haricot jusqu'à présent, et le nombre maximum de haricots contenus dans le conteneur (= occupation de la mémoire) Il peut ne pas être visible, donc cela peut avoir un impact sur la charge du processeur et la charge moyenne, c'est-à-dire que vous ne devez pas trop vous fier à l'initialisation différée.

Par conséquent, il est nécessaire d'envisager d'effectuer des tests tels que la désactivation temporaire de l'initialisation différée dans un environnement de test ou un environnement équivalent à la production.

ref

Recommended Posts

J'ai essayé l'initialisation paresseuse avec Spring Boot 2.2.0
J'ai essayé GraphQL avec Spring Boot
J'ai essayé Flyway avec Spring Boot
J'ai essayé Spring.
J'ai essayé le guide d'introduction de Spring Boot [Accès aux données avec JPA]
J'ai essayé de démarrer avec Swagger en utilisant Spring Boot
[J'ai essayé] Tutoriel de printemps
J'ai essayé Spring Batch
Télécharger avec Spring Boot
Je voulais classer la botte à ressort dans un multi-projet
Générer un code à barres avec Spring Boot
Hello World avec Spring Boot
J'ai essayé d'implémenter le téléchargement de fichiers avec Spring MVC
Implémenter GraphQL avec Spring Boot
J'ai essayé DI avec Ruby
Démarrez avec Spring Boot
05. J'ai essayé de supprimer la source de Spring Boot
Exécutez LIFF avec Spring Boot
Connexion SNS avec Spring Boot
J'ai essayé de démarrer avec Spring Data JPA
J'ai essayé la machine Spring State
Téléchargement de fichiers avec Spring Boot
Spring Boot commençant par copie
Hello World avec Spring Boot
Définir des cookies avec Spring Boot
Utiliser Spring JDBC avec Spring Boot
J'ai essayé UPSERT avec PostgreSQL.
Ajouter un module avec Spring Boot
Premiers pas avec Spring Boot
J'ai essayé de cloner une application Web pleine de bugs avec Spring Boot
J'ai essayé BIND avec Docker
Créer un micro service avec Spring Boot
J'ai écrit un test avec Spring Boot + JUnit 5 maintenant
Envoyer du courrier avec Spring Boot
Créez une application avec Spring Boot 2
J'ai essayé d'utiliser Spring + Mybatis + DbUnit
Liaison de base de données avec doma2 (Spring boot)
J'ai essayé l'analyse morphologique avec MeCab
Programmation Spring Boot avec VS Code
Jusqu'à "Hello World" avec Spring Boot
Obtenez des résultats de validation avec Spring Boot
J'ai essayé d'interagir avec Java
J'ai essayé la communication UDP avec Java
(Intellij) Hello World avec Spring Boot
Créez une application avec Spring Boot
Google Cloud Platform avec Spring Boot 2.0.0
[Java] Intégration LINE avec Spring Boot
À partir de Spring Boot 0. Utilisez Spring CLI
J'ai essayé de personnaliser Slim avec Scaffold
La coopération des messages a commencé avec Spring Boot
J'ai essayé le guide d'introduction de Spring Boot [Création d'un service Web RESTful]
J'ai essayé d'imprimer un formulaire avec Spring MVC et Jasper Reports 1/3 (paramètres Jasper Reports)
J'ai essayé d'imprimer un formulaire avec Spring MVC et Jasper Reports 3/3 (contrôle Spring MVC)
J'ai essayé de me connecter à MySQL en utilisant le modèle JDBC avec Spring MVC
J'ai créé un formulaire de recherche simple avec Spring Boot + GitHub Search API.
Guide de démarrage de Spring Boot [Utilisation d'un service Web RESTful]
Traitement lors du démarrage d'une application avec Spring Boot
J'ai essayé d'utiliser Realm avec Swift UI
Hello World avec Eclipse + Spring Boot + Maven