[Java Spring MVC] Ich möchte DI in meiner eigenen Klasse verwenden

Nachtrag 2018-11-05

In Laravel von PHP verursachte das globale Abrufen eines Objekts über DI-Auflösung von keiner Klasse keine Probleme (was meines Wissens nicht passiert ist), aber im Frühjahr beinhaltet es das nervige Element des Kontexts, also Laravel Es scheint, dass es nicht möglich ist, mit Hoi Hoi eine DI-Lösung mit einem solchen Kleber zu haben.

Wie üblich ist dies eine Geschichte in einem Zustand, in dem Spring Boot nicht verwendet wird. Daher ist es möglicherweise nicht der Fall, wenn Spring Boot eingeführt wird, aber zu diesem Zeitpunkt konnten wir noch nicht so viel untersuchen.


Zugewiesen an ein Web-System-Projekt mit Java Spring MVC. Spring Boot wird nicht verwendet, da es sich anscheinend um ein System handelt, das vor einiger Zeit hergestellt wurde. Ich bin noch neu in Java-Websystemen, daher ist dies sehr schwierig.

Spring MVC scheint eine Annotation wie "@Inject" für DI zu verwenden. Vor kurzem habe ich ein wenig über die domänengesteuerte Entwicklung gelernt, also habe ich versucht, ein einfaches Domänenobjekt zu erstellen, das mit dem Reparaturteil zusammenhängt, indem ich darüber nachgedacht habe, ein Domänenobjekt zu erstellen (ein Objekt, das eine leicht verständliche Arbeitseinheit trägt).

Ich habe jedoch gelernt, dass DI mit Anmerkungen nicht in einer Klasse verwendet werden kann, die nicht den Regeln von Spring MVC entspricht, dh in einer selbst erstellten Klasse. Als Ergebnis der Suche nach einer alternativen Methode habe ich sie so gefunden, wie sie ist, daher werde ich sie hier kurz zusammenfassen.

Überblick

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;


(Unterlassung)

    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
    HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
    ServletContext servletContext = httpServletRequest.getServletContext();
    WebApplicationContext webApplicationContext =
        WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

    //Instanz anhand des Bean-Definitionsnamens abrufen
    //Da es als Objekttyp zurückgegeben wird, wandeln Sie es in die gewünschte Klasse um
Zieltyp Variablenname= (In die gewünschte Form gießen) webApplicationContext.getBean("Name der Bean-Definition");

    //Get Bean Definition Namensliste getBean()Sie können die Zeichenfolge überprüfen, die als Argument für verwendet werden kann.
    String[] beanDefinitionNames = webApplicationContext.getBeanDefinitionNames();

ApplicationContext.getBean ("Bean-Definitionsname")

Holen Sie sich ServletContext

So ermitteln Sie den Namen der Bean-Definition

Beispielklasse

package Geben Sie den Paketnamen an;

import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 *Domänenobjekt
 *DI-Löser (DependencyInjectionSolver)
 *In einer selbstgemachten Klasse, die nicht von Spring verwaltet wird@DI mit Anmerkungen wie Inject funktioniert also nicht
 *Rufen Sie die DI-aufgelöste Instanz über diese Klasse ab.
 *
 *Beim Testen des Prozesses, der diese Klasse verwendet, sagt die JUnit Test-Klasse "@Kommentieren Sie "WebAppConfiguration".
 */
public class DependencyInjectionSolver {
  private static final Logger logger = LoggerFactory.getLogger(DependencyInjectionSolver.class);

  /**
   *ApplicationContext zum Abrufen von Beans durch diese Instanz
   */
  private WebApplicationContext webApplicationContext;

  public DependencyInjectionSolver() {
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
    HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
    ServletContext servletContext = httpServletRequest.getServletContext();
    this.webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
  }

  /**
   *Erhalten Sie den Bean-Definitionsnamen und rufen Sie die DI-aufgelöste Instanz ab.
   *Da es als Objekttyp zurückgegeben wird, werfen Sie es auf die Erfassungsseite.
   *
   * @param string Name der Bean-Definition
   * @return Object
   */
  public Object getBeanByBeanName(String beanName) {
    return this.webApplicationContext.getBean(beanName);
  }

  /**
   *Rufen Sie eine Liste der definierten Bean-Definitionsnamen ab.
   *GetBeanByBeanName für die Namen in dieser Liste()Kann als Argument von verwendet werden.
   *
   * @return List<string>Liste der Bean-Definitionsnamen
   */
  public List<String> gettableBeanNames() {
    String[] beanDefinitionNames = this.webApplicationContext.getBeanDefinitionNames();
    return Arrays.asList(beanDefinitionNames);
  }
}

Benutzerseite

DependencyInjectionSolver diSolver = new DependencyInjectionSolver();
Variablenname wie Schnittstellenname= (Schnittstellenname usw.) diSolver.getBeanByBeanName("Name der Bean-Definition");

Recommended Posts

[Java Spring MVC] Ich möchte DI in meiner eigenen Klasse verwenden
Ich möchte ES2015 auch in Java verwenden! → (´ ・ ω ・ `)
Ich möchte @Autowired in Servlet verwenden
[java] Was ich getan habe, als ich Listen in meiner eigenen Klasse verglichen habe
Ich möchte eine E-Mail in Java senden.
Ich möchte Java8 für jeden mit Index verwenden
rsync4j - Ich möchte rsync in Java berühren.
Mein Memorandum, dass ich ValidationMessages.properties UTF8 in Spring Boot erstellen möchte
Ich möchte die praktischen Funktionen von Clojure in Kotlin nutzen
Ich möchte so etwas wie "cls" in Java machen
Ich möchte auch in Laradock Fischschalen verwenden! !!
Verwendung der Java-Klasse
Ich möchte PowerMock in einer Klasse verwenden, die parametrisierte Tests und gewöhnliche Tests kombiniert
Aufrufen und Verwenden der API in Java (Spring Boot)
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben
Ich habe versucht, die Objektorientierung auf meine Weise zusammenzufassen.
Ich möchte die if-else-Anweisung für bedingte Verzweigungen in Java vereinfachen
Wie man Lombok im Frühling benutzt
Ich steckte in einer Falle fest, als ich meine eigenen Klassen equals und hashCode in Java mit IDE generierte
Verwendung von Klassenmethoden [Java]
Wie verwende ich Klassen in Java?
[Java] Verwendung der Math-Klasse
Ich möchte nur Java mit Eclipse auf meinem Mac schreiben
Ich habe versucht, Java-Anfänger so einzustellen, dass sie Tastenkombinationen in Eclipse verwenden
[Java] Ich möchte mit dem Schlüssel im Objekt eindeutig arbeiten
[Spring Boot] Ich möchte meine eigene Eigenschaftendatei hinzufügen und den Wert mit env.getProperty () abrufen.
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Ich möchte DBViewer mit Eclipse 2018-12 verwenden! !!
[Verarbeitung × Java] Verwendung der Klasse
Verwendung der Java Scanner-Klasse (Hinweis)
Ich möchte Java-Updates insgesamt stoppen
[Java] Verwendung der Calendar-Klasse
[* Java *] Ich habe am JJUG CCC 2019 Spring teilgenommen
Ich möchte Bilder mit REST Controller von Java und Spring anzeigen!
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (PowerMockito Edition)
(Beschränkt auf Java 7 oder höher) Ich möchte, dass Sie Objekte in Objects.equals vergleichen
Ich möchte die IP-Adresse erhalten, wenn ich mit Java eine Verbindung zu Wi-Fi herstelle
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
"Lehrer, ich möchte im Frühjahr eine Anmeldefunktion implementieren" ① Hallo Welt
Welche Klasse sollte verwendet werden, um Datum und Uhrzeit in der Rails-App abzurufen (Time, DateTime, TimeWithZone)?
[Java] Verwendung der FileReader-Klasse und der BufferedReader-Klasse
Java-Methodenaufruf von RPG (Methodenaufruf in eigener Klasse)
Sogar in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (Javassist zweite Abkochung)
So erhalten Sie eine Klasse von Element in Java
Ich möchte APP_HOME an Logback in Gradle übergeben
Ich möchte, dass Sie Scala vorerst als besseres Java verwenden
[JAVA] [Spring] [MyBatis] Verwenden Sie IN () mit SQL Builder
Ich möchte schnell von Java nach SQLite schreiben
Ich habe versucht, Alexa-Fähigkeiten mit Java zu erstellen
Lassen Sie uns eine TODO-Anwendung mit Java 2 erstellen. Ich möchte eine Vorlage mit Spring Initializr erstellen und eine Hello-Welt erstellen
[Java] Spring DI ③
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 (Black Magic) ausgeben.
Ich möchte den Wert in Ruby erhalten
[Java] Verwendung der Kalenderklasse und der Datumsklasse