[JAVA] Essayez DI avec Micronaut

DI avec Micronaut

Micronaut semble avoir un mécanisme DI (Dependency Injection).

Inversion of Control

En tant que fonctionnalité,

Il semble y avoir quelque chose comme ça.

Scope utilisé dans Micronaut DI

Micronaut utilise le JSR-330 pour l'annotation.

https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html

En plus du @ Singleton inclus dans JSR-330, cliquez ici pour l'annotation de portée utilisée par Micronaut.

Scopes

Il y a des choses étranges.

La portée «@ Context» représente un bean qui doit être initialisé et arrêté lorsque le «BeanContext» démarre et se termine.

Micronaut semble initialiser paresseusement un bean Singleton, vous pouvez donc utiliser l'annotation @ Context pour l'initialiser lorsque le BeanContext démarre. Cela dit, Micronaut est conçu pour créer un nombre minimal de beans au démarrage, donc la spécification @ Context semble être conservatrice.

Il y a des choses étranges comme @ ThreadLocal. «@ Infrastructure» semble être un type stéréo de «@ Singleton».

Il existe également une portée actualisable appelée @ Refreshable, et il semble que vous puissiez actualiser avec le point de terminaison / refresh ou RefreshEvent.

Refreshable Scope

Cliquez ici pour les packages avec des annotations ici.

https://docs.micronaut.io/1.0.4/api/io/micronaut/context/annotation/package-summary.html

Cependant, l'annotation @ Controller qui apparaît dans Quick Start est également une sorte d'annotation de portée. Il semble que ce ne soit pas la seule chose en tout ...

Cliquez également ici pour les types de conteneurs compatibles DI (tels que ʻOptional et ʻIterable).

Injectable Container Types

Il semble y avoir aussi des qualificatifs.

Bean Qualifiers

Touchons un peu plus facilement.

environnement

Cliquez ici pour cet environnement.

$ mn -V
| Micronaut Version: 1.0.4
| JVM Version: 1.8.0_191

Créez un modèle pour votre application.

$ mn create-app hello-di --build maven
$ cd hello-di

Exemple d'application

Écrivons un exemple simple en utilisant les portées @ Singleton et @ Prototype.

Service @ Singleton.

src/main/java/hello/di/service/SingletonService.java

package hello.di.service;

import javax.inject.Singleton;

@Singleton
public class SingletonService {
    public String message() {
        return "Hello Singleton Bean";
    }
}

Utilisez ce Service, Controller.

src/main/java/hello/di/controller/SingletonBeanController.java

package hello.di.controller;

import hello.di.service.SingletonService;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/singleton")
public class SingletonBeanController {
    SingletonService singletonService;

    public SingletonBeanController(SingletonService singletonService) {
        this.singletonService = singletonService;
    }

    @Get(produces = MediaType.TEXT_PLAIN)
    public String index() {
        return singletonService.message() + " from " + singletonService.getClass().getName() + "@" + singletonService.hashCode();
    }
}

Il semble que l'injection de constructeur soit possible.

    SingletonService singletonService;

    public SingletonBeanController(SingletonService singletonService) {
        this.singletonService = singletonService;
    }

Essayez également d'émettre un code de hachage pour confirmer que les instances sont identiques.

    @Get(produces = MediaType.TEXT_PLAIN)
    public String index() {
        return singletonService.message() + " from " + singletonService.getClass().getName() + "@" + singletonService.hashCode();
    }

Ensuite, un service @ Prototype.

src/main/java/hello/di/service/PrototypeService.java

package hello.di.service;

import io.micronaut.context.annotation.Prototype;

@Prototype
public class PrototypeService {
    public String message() {
        return "Hello Prototype Bean";
    }

}

Utilisez ce Service, Controller.

src/main/java/hello/di/controller/PrototypeBeanController.java

package hello.di.controller;

import javax.inject.Inject;

import hello.di.service.PrototypeService;
import io.micronaut.context.ApplicationContext;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/prototype")
public class PrototypeBeanController {
    @Inject
    ApplicationContext applicationContext;

    @Get(produces = MediaType.TEXT_PLAIN)
    public String index() {
        PrototypeService prototypeService = applicationContext.getBean(PrototypeService.class);
        return prototypeService.message() + " from " + prototypeService.getClass().getName() + "@" + prototypeService.hashCode();
    }
}

Controller semble être Singleton, et quand je l'injecte tel quel, il devient la même instance même s'il s'agit de @ Prototype, alors j'ai décidé de l'obtenir à partir de ʻApplicatoinContext` ...

    @Get(produces = MediaType.TEXT_PLAIN)
    public String index() {
        PrototypeService prototypeService = applicationContext.getBean(PrototypeService.class);
        return prototypeService.message() + " from " + prototypeService.getClass().getName() + "@" + prototypeService.hashCode();
    }

Est-ce parce qu'il n'y a pas de proxy client?

De plus, il semble que l'annotation @ Inject puisse être utilisée.

    @Inject
    ApplicationContext applicationContext;

L'injection de constructeur de ʻApplicationContext` est également OK.

    PrototypeService prototypeService;

    public PrototypeBeanController(PrototypeService prototypeService) {
        this.prototypeService = prototypeService;
    }

La classe avec la méthode main est omise car elle est toujours générée automatiquement.

Vérification

Accédez à Controller en utilisant @ Singleton`` Service.

$ curl localhost:8080/singleton
Hello Singleton Bean from hello.di.service.SingletonService@56609473


$ curl localhost:8080/singleton
Hello Singleton Bean from hello.di.service.SingletonService@56609473


$ curl localhost:8080/singleton
Hello Singleton Bean from hello.di.service.SingletonService@56609473

J'ai pu confirmer que le DI fonctionnait et que le même «Service» a été retourné.

Ensuite, @ Prototype.

$ curl localhost:8080/prototype
Hello Prototype Bean from hello.di.service.PrototypeService@1219715735


$ curl localhost:8080/prototype
Hello Prototype Bean from hello.di.service.PrototypeService@1284304729


$ curl localhost:8080/prototype
Hello Prototype Bean from hello.di.service.PrototypeService@1807347832

Ici, vous pouvez voir que le Service d'une instance différente est renvoyé.

Fichier généré automatiquement

Au fait, quel type de fichier a été généré par Annotation Processor?

$ tree target
target
├── classes
│   ├── META-INF
│   │   ├── hello-di.kotlin_module
│   │   └── services
│   │       └── io.micronaut.inject.BeanDefinitionReference
│   ├── application.yml
│   ├── hello
│   │   └── di
│   │       ├── Application.class
│   │       ├── controller
│   │       │   ├── $PrototypeBeanControllerDefinition$$exec1$$AnnotationMetadata.class
│   │       │   ├── $PrototypeBeanControllerDefinition$$exec1.class
│   │       │   ├── $PrototypeBeanControllerDefinition.class
│   │       │   ├── $PrototypeBeanControllerDefinitionClass$$AnnotationMetadata.class
│   │       │   ├── $PrototypeBeanControllerDefinitionClass.class
│   │       │   ├── $SingletonBeanControllerDefinition$$exec1$$AnnotationMetadata.class
│   │       │   ├── $SingletonBeanControllerDefinition$$exec1.class
│   │       │   ├── $SingletonBeanControllerDefinition.class
│   │       │   ├── $SingletonBeanControllerDefinitionClass$$AnnotationMetadata.class
│   │       │   ├── $SingletonBeanControllerDefinitionClass.class
│   │       │   ├── PrototypeBeanController.class
│   │       │   └── SingletonBeanController.class
│   │       └── service
│   │           ├── $PrototypeServiceDefinition.class
│   │           ├── $PrototypeServiceDefinitionClass$$AnnotationMetadata.class
│   │           ├── $PrototypeServiceDefinitionClass.class
│   │           ├── $SingletonServiceDefinition.class
│   │           ├── $SingletonServiceDefinitionClass$$AnnotationMetadata.class
│   │           ├── $SingletonServiceDefinitionClass.class
│   │           ├── PrototypeService.class
│   │           └── SingletonService.class
│   └── logback.xml
└── generated-sources
    └── annotations

9 directories, 25 files

D'une manière ou d'une autre, diverses choses sont faites.

Il semble qu'un fichier pour le fournisseur de services a été créé, donc le contenu ici aussi.

target/classes/META-INF/services/io.micronaut.inject.BeanDefinitionReference

hello.di.service.$PrototypeServiceDefinitionClass
hello.di.service.$SingletonServiceDefinitionClass
hello.di.controller.$SingletonBeanControllerDefinitionClass
hello.di.controller.$PrototypeBeanControllerDefinitionClass

Pour l'instant, j'ai pu confirmer l'ambiance.

Recommended Posts

Essayez DI avec Micronaut
Essayez de créer avec Trailblazer
Essayez WebSocket avec jooby
Hello World avec Micronaut
Fonction sans serveur avec Micronaut
Essayez d'utiliser un conteneur DI avec Laravel et Spring Boot
J'ai essayé DI avec Ruby
Essayez d'utiliser GloVe avec Deeplearning4j
Essayez la connexion DB avec Java
Essayez gRPC avec Java, Maven
Accédez à Apache Kafka avec Micronaut
Essayez de lire XML avec JDOM
Ecrire un serveur réactif avec Micronaut
Essayez d'exécuter cloudera manager avec docker
Essayez d'implémenter recaptcha avec Jetty intégré.
Essayez de manipuler les tableaux PostgreSQL avec JDBC
Essayez d'utiliser Redis avec Java (jar)
Ajouter une validation de bean avec Micronaut (Java)
Essayez l'analyse syntaxique des phrases anglaises avec Stanford CoreNLP
Essayez la communication bidirectionnelle avec gRPC Java
Essayez d'exécuter MySql et Blazor avec docker-compose
Essayons WebSocket avec Java et javascript!
Essayez d'utiliser Spring Boot avec VS Code
Essayez de vous serrer la main avec ARKit + Metal
Essayez d'implémenter une fonction de connexion avec Spring-Boot
Essayez de gérer les bibliothèques Java avec AWS CodeArtifact
Essayer avec la déclaration de ressources dans l'application Web
Essayez d'utiliser la télécommande Wii en Java