[JAVA] Ich habe Spring Boot seit einem Monat nicht mehr verstanden

Einführung

Es ist einen Monat her, seit ich eine Anwendung mit Spring Boot implementiert habe. Es gibt jedoch noch viele Teile, die ich nicht gut verstehe, daher werde ich das, was ich hier studiert habe, als Notenänderung zusammenfassen: v:

Was ist DI (Dependency Injection)?

Eine Art von IoC (Inversion of Control). Es scheint "ServiceLocator" in IoC zu geben, aber bitte lesen Sie hier.

DI ist eine Abkürzung für Dependency Injection, die die Grundlage aller Frühlingszeiten bildet. Die einfache Erklärung von DI lautet *** Instanzverwaltung ***.

Was ist Instanzverwaltung ...?

Was ist Abhängigkeitsinjektion ...? Was macht DI?

Siehe hier für die Bedeutung von "Abhängigkeit" und "Injektion" in DI. Wenn Sie das Wort "Injektion von Abhängigkeit" nicht verstehen, können Sie es in "Objekt injizieren" ändern. DI macht es einfach, die beiden oben genannten Dinge gleichzeitig zu tun, aber es gibt viele andere. : nach unten zeigen:

Suchen Sie eine von DI verwaltete Klasse (Komponentenscan)

Wenn Spring gestartet wird, wird ein Prozess namens Komponentenscan ausgeführt und sucht nach einer Klasse mit den folgenden von DI verwalteten Zielanmerkungen. @Component @Controller @Service @Repository @Configuration @RestController @ControllerAdvice @ManagedBean @Named

Instanzerstellung und -injektion

Im DI-Behälter registrierte Bohnen instanziieren und injizieren. Nach dem Sammeln der DI-Zielklassen (Beans) erstellt DI diese Instanzen (neu). Anschließend wird die generierte Instanz mit der folgenden Methode injiziert (zugewiesen).

Injektionsmethode

*** - Feldinjektion (veraltet) ***

Für die Feldinjektion wird eine Instanz einfach durch Hinzufügen von "@ Autowired" zum Feld (Mitgliedsvariable) injiziert (zugewiesen).

@Autowired
private SampleService sampleService;

Es wurde jedoch aufgrund der folgenden Nachteile veraltet ...

  1. Sie können nur verspotten, wenn Sie beim Erstellen des Testcodes einen DI-Container verwenden.
  2. Das endgültige Attribut kann dem Feld nicht hinzugefügt werden und es kann nicht unveränderlich sein.

Jetzt verwenden wir die folgende Konstruktorinjektion:

*** ・ Konstruktorinjektion ***

@Service
@Transactional
public class SampleService {

  private final SampleRepository sampleRepository;

  // spring4.Nach 3, wenn es einen Konstruktor gibt@Autowired kann weggelassen werden
  @Autowired
  public SampleService(SampleRepository sampleRepository) {
    this.sampleRepository = sampleRepository;
  }

}

Nutzen Sie Lombok, um das Schreiben zu vereinfachen. Kommentieren Sie einfach @ RequiredArgsConstructor zur Klasse: point_down:

@Service
@Transactional
@RequiredArgsConstructor
public class SampleService {

  private final SampleRepository sampleRepository;

}

Was ist eine Bohne?

Die auf dem DI-Container verwaltete Klasse heißt "Bean". Verweist auf eine Klasse mit der Annotation "@ Component" oder "@ Controller" oder auf eine Klasse, die im DI-Container mit der als "@ Bean" geschriebenen Methode registriert ist.

So implementieren Sie DI

So implementieren Sie JavaConfig DI

Definieren Sie zunächst die Bean, die im DI-Container registriert werden soll.

JavaConfig.java


@Configuration
public class JavaConfig {
  @Bean
  public SampleComponent sampleComponent {
    return new SampleComponent();
  }
  @Baan
  public SampleController sampleService {
    return new SampleService();
  }
}

Jetzt wird der Rückgabewert des Getters mit @ Bean als Bean des DI-Containers registriert. In JavaConfig müssen Methoden für Instanzen vorbereitet werden, die von DI-Containern verwaltet werden. Sie können jedoch die Werte festlegen, die beim Erstellen einer Instanz an den Konstruktor usw. übergeben werden sollen, und Sie können die JavaConfig-Klasse zwischen der Produktionsumgebung und der Entwicklungsumgebung wechseln.

Annotationsbasierte DI-Implementierung

Auf Annotationsbasis registriert Spring automatisch Klassen mit "@ Component" und "@ Controller" im DI-Container.

Was ist DI-Lebenszyklusmanagement ...?

Lifecycle Management ist das Management der Instanzerstellung (neu) und -zerstörung. Wenn Sie ein Servlet zum Erstellen einer Webanwendung verwenden, wird die Instanz im Sitzungsbereich oder im Anforderungsbereich registriert. Sie müssen jedoch genau wissen, wann die Instanz zerstört wird.

Was ist ein Bereich ...?

Der Sitzungsbereich und der Anforderungsbereich sind die Ablaufdaten der Instanz. Die Ablaufdaten der beiden Bereiche unterscheiden sich wie folgt.

Sitzungsumfang

Das Ablaufdatum reicht vom Anmelden des Benutzers bis zum Abmelden. Beispielsweise können Sie Informationen haben, z. B. ob der Benutzer als Sitzungsbereich angemeldet ist. Der folgende Code ruft den Code ab, den ich beim Erstellen einer Anwendung verwendet habe, die OAuth verwendet.

OAuthDTO.java


@Data
@Component
@SessionScope
public class OAuthDTO {
  private boolean isLogin;
}

Umfang anfordern

Eine HTTP-Anforderung läuft ab. Beispielsweise ist der Bereich vom Benutzeranmeldebildschirm bis zum Übergang zum Benutzerprofilbildschirm durch Drücken der Anmeldeschaltfläche der Bereich des Anforderungsbereichs. Ich habe es im Interceptor (https://qiita.com/kyabetsuda/items/78a61bfff859fbc9c63f) verwendet, der verarbeitet wird, bevor der Controller aufgerufen wird.

OAuthInterceptor.java


@Component
@RequiredArgsConstructor
@RequestScope
public class OAuthInterceptor extends HandlerInterceptorAdapter {
  private final OAuthDTO oAuthDTO;

  /** {@inheritDoc} */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws AuthenticationException {
    if (!oAuthDTO.isLogin()) {
      throw new AuthenticationException("Bitte loggen Sie sich ein.");
    }
    return true;
  }
}

Andere Bereiche

*** leton Singleton *** Erstellen Sie nur eine Instanz, wenn Spring startet. Nach der Erstellung wird eine Instanz freigegeben und verwendet. Wenn Sie aufgrund der Standardeinstellung die Annotation "@ Scope" nicht hinzufügen, sind alle Singleton-Annotationen.

*** · Prototyp *** Jedes Mal, wenn Sie eine Bean erhalten, wird eine Instanz erstellt

*** ・ globalSession *** Instanzen werden für jede globale Sitzung in der Portlet-Umgebung erstellt. Es kann nur für Webanwendungen verwendet werden, die Portlets unterstützen.

*** ・ Anwendung *** Für jeden Kontext des Servlets werden Instanzen erstellt.

Wie oben erwähnt, können Sie eine Instanz mithilfe der Annotation "@ Scope" einfach erstellen und zerstören.

Dinge, auf die Sie in DI achten sollten

singleton Wenn Sie die Annotation "@ Scope" nicht hinzufügen, wird die Instanz mit Singleton erstellt. Das heißt, es kann nur eine Instanz des Objekts erstellt werden. Wenn Sie den Umfang nicht kennen, kann dies zu Fehlern führen.

Unterschied im Umfang

Zum Beispiel, wenn eine Instanz des Singleton-Bereichs ein Sitzungsbereichsobjekt hat.

OAuthDTO.java


@Data
@Component
@SessionScope
public class OAuthDTO {
  private boolean isLogin;
}

OAuthService.java


@Service
@RequiredArgsConstructor
public class OAuthService {
 
   private final OAuthDTO oAuthDTO;

}

~~ In diesem Fall wird die Bean (OAuthDTO.java) mit dem Sitzungsbereich in den Singleton-Bereich geändert. ~~

*** Hinzugefügt am 28. April *** Es tut mir Leid. Dieser Teil war falsch: Bogen:

@ SessionScope ist seit Spring 4.3 verfügbar und war ursprünglich @Scope(value = “session”, proxyMode = ScopedProxyMode.TARGET_CLASS) ist. Also heißt proxyMode = ScopedProxyMode.TARGET_CLASS *** Scoped Proxy ***, der die Bean injiziert, während sie in Proxy eingeschlossen ist, und wenn Sie die Methode der injizierten Bean aufrufen, sieht sie tatsächlich aus dem DI-Container aus. Die Methode wird an die hochgeladene Bean delegiert.

Mit anderen Worten ... Es erfolgt keine Änderung des Umfangs. Derzeit gibt es mit "Scoped-Proxy" kein Problem, selbst wenn der Controller und der Interceptor so implementiert sind, dass sie Dinge mit einem engeren Umfang als sie selbst empfangen, ohne sich um sie zu kümmern.

Für Prototypen usw. ist es gut, sich auf Folgendes zu beziehen.

Der Code im obigen Beispiel ist jedoch nicht korrekt. Durch Einfügen von OAuthDTO.java in OAuthService.java hat die Service-Klasse einen Status. Die Service-Klasse wird nicht nur von der *** Controller-Klasse *** aufgerufen. Wenn Sie also vor dem Gültigkeitsbereich einen Status haben, der an einen bestimmten Kontext gebunden ist, z. B. eine HTTP-Anforderung, wird er auf einer Route ausgeführt, die nicht vorhanden ist. Manchmal stellt sich die Frage, woher die Instanz stammt.

Daher sollte im Code im obigen Beispiel OAuthDTO.java in die Controller-Klasse eingefügt werden.

Informationen zur tatsächlichen Implementierungsmethode finden Sie im Folgenden.

Site-Zusammenfassung, auf die hier häufig Bezug genommen wird

Anmerkung

Lombok

Codeüberprüfungspunkte

Recommended Posts

Ich habe Spring Boot seit einem Monat nicht mehr verstanden
So schreiben Sie einen Komponententest für Spring Boot 2
[Spring Boot] So erstellen Sie ein Projekt (für Anfänger)
Ich habe jetzt einen Test mit Spring Boot + JUnit 5 geschrieben
Einführung von Spring Boot2, einem Java-Framework für die Webentwicklung (für Anfänger)
Spring Boot zum Lernen von Anmerkungen
Ich habe mit Spring Boot ein einfaches MVC-Beispielsystem erstellt
Ich habe das Spring Boot-Einführungshandbuch [Erstellen eines RESTful-Webdiensts] ausprobiert.
So erstellen Sie mit SPRING INITIALIZR einen Hinadan für ein Spring Boot-Projekt
Ich habe ein einfaches Suchformular mit Spring Boot + GitHub Search API erstellt.
Spring Boot Erste Schritte [Konsumieren eines RESTful-Webdienstes]
Eine Geschichte, die ich als Nicht-Ingenieur endlich verstanden habe
Spring Boot zum ersten Mal
Häufige Anmerkungen für Spring Boot-Tests
Verwenden Sie DBUnit für den Spring Boot-Test
Ich habe GraphQL mit Spring Boot ausprobiert
Ein Memo, das Spring Boot berührte
Ich habe Flyway mit Spring Boot ausprobiert
Erstellen Sie mit Intellij ein Spring Boot-Projekt und beenden Sie es sofort nach dem Start
Ich habe die Verwendung der Schlangenhülle für den Variablennamen in Spring Boot nicht mehr verstanden
[Spring Boot] Ich bin auf einen Methodenaufruf-Count-Test gestoßen (Spock-Framework)
[LINE BOT] Ich habe einen Ramen BOT mit Java (Maven) + Heroku + Spring Boot (1) gemacht.
Was ist eine Spring Boot-Originaldatei?
WebMvcConfigurer-Memorandum von Spring Boot 2.0 (Spring 5)
Ich habe Lazy Initialization mit Spring Boot 2.2.0 ausprobiert
Ich habe ein Plug-In für IntelliJ IDEA erstellt
03. Ich habe eine Anfrage von Spring Boot an die Postleitzahlensuch-API gesendet
Ich habe versucht, eine Webanwendung voller Fehler mit Spring Boot zu klonen