Eingehende Untersuchung der automatischen Montage von Spring Boot

Modusanmerkung

Stereotyp Annotation - Modus als Anmerkungen bekannt, Frühlings- und Notizen im gemeinsamen Modus haben @Service, @Repository, @Controllerund so weiter, sie werden als „abgeleitet“ von @ComponentKommentaren. Wir alle wissen, dass alle mit @ComponentAnmerkungen versehenen Klassen bis zum Frühjahr gescannt und in den IOC-Container aufgenommen werden. @ComponentDie durch die abgeleiteten Anmerkungen mit Anmerkungen versehenen Klassen werden auch in den IOC-Container gescannt. Im Folgenden lernen wir hauptsächlich @Componentdie "Ableitung" und "Überlagerung" durch Anmerkungen im benutzerdefinierten Modus .

@Komponente "Derivat"

Erstellen Sie ein neues Spring Boot-Projekt. Die Spring Boot-Version ist 2.1.0.RELEASE, Autoconfig artifactIdund spring-boot-starter-webAbhängigkeiten werden eingeführt . Die Projektstruktur ist wie folgt:

Im com.example.demoFall der neuen annotationPaket und erstellen Sie einen FirstLevelServiceKommentar:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface FirstLevelService {
    String value() default "";
}

Diese Annotation wird durch @ServiceAnnotationen definiert , @Serviceund Sie werden feststellen, dass sie beim Anzeigen des Quellcodes mit Annotationen @Componentversehen ist. Ihre hierarchische Beziehung lautet also:

└─ @ Component
     └─ @ Service
          └─ @ FirstLevelService

Das @FirstLevelServiceist @Componentaus dem Annotationsmodus abgeleitet, wir müssen testen, ob eine markierte Klasse in den IOC-Container gescannt werden kann:

Klicken Sie unter com.example.demoNeu unter servicedem Paket auf eine TestServiceKlasse:

@SecondLevelService
public class TestService {
}

In com.example.demodem neuen bootstrapPaket, und dann eine erstellen ServiceBootStrapKlasse für das Testregister TestServiceund vom IOC Schiff erhalten:

@ComponentScan("com.example.demo.service")
public class ServiceBootstrap {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(ServiceBootstrap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        TestService testService = context.getBean("testService", TestService.class);
        System.out.println("TestService Bean: " + testService);
        context.close();
    }
}

Führen Sie die Hauptmethode dieser Klasse aus. Die Konsolenausgabe lautet wie folgt:

@Komponente "hierarchisch"

Wir com.example.demo.annotationerstellen eine weitere SecondLevelServiceAnnotationsdefinition unter dem Pfad . Die Annotation ist durch Folgendes @FirstLevelServicegekennzeichnet:

Zu diesem Zeitpunkt lautet die hierarchische Beziehung:

└─ @ Component
     └─ @ Service
           └─ @ FirstLevelService
                 └─ @ SecondLevelService

Wir werden die TestServiceobige Annotation durch die Hauptmethode ersetzen @SecondLevelServiceund sie dann erneut ausführen ServiceBootStrap. Die Ausgabe lautet wie folgt:

Es ist ersichtlich, dass das Ergebnis auch erfolgreich ist.

Hierbei ist zu beachten, dass die @ComponentAnnotation nur eine Wertattributdefinition enthält, sodass die "abgeleitete" Annotation nur eine Wertattributdefinition enthalten kann.

@ Modul-Treiber aktivieren

@EnableModultreiber werden nach Spring Framework 3.1 unterstützt. Im Allgemeinen ist das Modul hier eine Sammlung von Komponenten, um eine bestimmte Funktion zu erreichen. Über den @EnableModultreiber können wir die entsprechende Modulfunktion einschalten.

@EnableDas Modullaufwerk kann in zwei Implementierungsmodi unterteilt werden: "Anmerkungslaufwerk" und "Schnittstellenprogrammierung". Das Folgende ist eine Demonstration nacheinander:

Annotation Driven

Im Frühjahr kann ein annotationsgesteuertes Beispiel aus dem @EnableWebMvcQuellcode angezeigt werden:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

Diese Anmerkung erfolgt durch @ImportImportieren einer Konfigurationsklasse DelegatingWebMvcConfiguration:

Diese Konfigurationsklasse wird von ihr geerbt WebMvcConfigurationSupport, wodurch einige Bean-Deklarationen definiert werden.

Daher importiert der annotationsgesteuerte @EnableModultreiber tatsächlich @Importeine Konfigurationsklasse, um die Komponentenregistrierung des entsprechenden Moduls zu realisieren. Wenn diese Komponenten im IOC-Container registriert sind, kann die entsprechende Funktion dieses Moduls verwendet werden.

Definieren wir einen @EnableModultreiber basierend auf Annotation- gesteuert.

Klicken Sie unter com.example.demoNeu unter configurationdem Paket auf eine HelloWorldConfigurationKonfigurationsklasse:

@Configuration
public class HelloWorldConfiguration {

    @Bean
    public String hello() {
        return "hello world";
    }
}

In dieser Konfigurationsklasse wird eine benannte helloBean mit Inhalt definiert hello world.

Beim com.example.demo.annotationErstellen einer nächsten EnableHelloWorldAnmerkungsdefinition:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorld {
}

Wir haben @Importdie Konfigurationsklasse importiert, die wir gerade für diese Anmerkungsklasse erstellt haben .

Beim com.example.demo.bootstrapErstellen einer nächsten TestEnableBootstapStartklasse zum Testen der @EnableHelloWorldAnnotation gilt Folgendes:

@EnableHelloWorld
public class TestEnableBootstap {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(TestEnableBootstap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String hello = context.getBean("hello", String.class);
        System.out.println("hello Bean: " + hello);
        context.close();
    }
}

Führen Sie die Hauptmethode dieser Klasse aus. Die Konsolenausgabe lautet wie folgt:

Erklären Sie, dass unsere benutzerdefinierte Annotation gesteuert werden kann @EnableHelloWorld.

Schnittstellenprogrammierung

Zusätzlich zur Verwendung der obigen Methode können wir auch @EnableModulantriebe durch Schnittstellenprogrammierung implementieren . Im Frühjahr gibt es @EnableCachingAnmerkungen, die auf der Schnittstellenprogrammierung basieren . Überprüfen Sie den Quellcode:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({CachingConfigurationSelector.class})
public @interface EnableCaching {
    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

EnableCachingAnmerkungen @Importimportieren eine CachingConfigurationSelectorKlasse, die indirekt die ImportSelectorSchnittstelle implementiert . In der  eingehenden Untersuchung der Spring-Komponentenregistrierung  haben wir eingeführt, dass die ImportSelectorKomponentenregistrierung durch erreicht werden kann .

Daher @Enablebesteht das Wesentliche beim Implementieren der Modulsteuerung durch die Schnittstellenprogrammierung darin @Import, die Schnittstellenimplementierungsklasse zu importieren ImportSelector, die die Komponenten definieren kann, die im IOC-Container registriert werden müssen, um die Registrierung der entsprechenden Komponenten des entsprechenden Moduls zu realisieren.

Als nächstes werden wir es nach dieser Idee wieder realisieren:

Im com.example.demoneuen selectorPaket dann ein neuer Pfad in den HelloWorldImportSelectorimplementierten ImportSelectorSchnittstellen:

public class HelloWorldImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{HelloWorldConfiguration.class.getName()};
    }
}

Wenn Sie die Bedeutung des obigen Codes nicht verstehen, können Sie den Artikel über das eingehende Erlernen der Registrierung von Spring-Komponenten lesen .

Dann ändern wir EnableHelloWorld:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldImportSelector.class)
public @interface EnableHelloWorld {
}

Der obige Import ist HelloWorldImportSelectornicht HelloWorldConfiguration.

Führen Sie TestEnableBootstapdie Hauptmethode erneut aus, und Sie werden feststellen, dass die Ausgabe dieselbe ist.

Automatische Montage

Die unterste Schicht der automatischen Montagetechnologie in Spring Boot verwendet hauptsächlich die folgenden Technologien:

  1. Annotationsbaugruppe für den Federmodus

  2. Spring @Enable Modulbaugruppe

  3. Federbedingte Montage (eingeführt in der eingehenden Untersuchung der Registrierung von Federkomponenten )

  4. Federfabrik-Lademechanismus

Die Implementierungsklasse des Spring Factory-Lademechanismus lautet SpringFactoriesLoader: Überprüfen Sie den Quellcode:

Die Methode dieser Klasse liest die Konfigurationsdatei spring.factories im Verzeichnis META-INF. Wir überprüfen die Datei unter spring-boot-autoconfigure-2.1.0.RELEASE.jar:

Wenn die Startklasse @EnableAutoConfigurationmarkiert ist, werden alle Klassen im obigen Screenshot von Spring gescannt, um festzustellen, ob sie zur Verwaltung in den IOC-Container aufgenommen werden können.

Zum Beispiel org.springframework.boot.autoconfigure.data.redis.RedisAutoConfigurationder Quellcode, den wir angesehen haben :

Es ist ersichtlich, dass in dieser Kategorie einige Anmerkungen markiert sind, darunter @ConfigurationModusanmerkungen, @EnableConfigurationPropertiesModulmontagetechnologie und ConditionalOnClassbedingte Montagetechnologie. Dies steht im Einklang mit den oben aufgeführten Haupttechnologien der automatischen Montage von Spring Boot, sodass wir eine Implementierung der automatischen Montage basierend auf dieser Idee anpassen können.

Erstellen Sie eine neue Konfigurationsklasse HelloWorldAutoConfiguration:

@Configuration
@EnableHelloWorld
@ConditionalOnProperty(name = "helloworld", havingValue = "true")
public class HelloWorldAutoConfiguration {
}

Erstellen Sie dann ein neues META-INF-Verzeichnis unter dem Ressourcenverzeichnis und erstellen Sie eine spring.factories-Datei:

# Automatisch konfigurieren
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
com.example.demo.configuration.HelloWorldAutoConfiguration

Fügen Sie dann die helloworld=trueKonfiguration in die Konfigurationsdatei application.properties ein

helloworld = wahr

Zum Schluss erstellen EnableAutoConfigurationBootstrap, testen, HelloWorldAutoConfigurationob es funktioniert:

@EnableAutoConfiguration
public class EnableAutoConfigurationBootstrap {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String hello = context.getBean("hello", String.class);
        System.out.println("hello Bean: " + hello);
        context.close();
    }
}

Führen Sie die Hauptmethode aus. Die Konsolenausgabe lautet wie folgt:

Es zeigt, dass unsere kundenspezifische automatische Montage erfolgreich war.

Nachfolgend finden Sie eine kurze Analyse der laufenden Logik des Codes:

  • Der werkseitige Lademechanismus von Spring liest automatisch den Inhalt der Datei spring.factories im META-INF-Verzeichnis.

  • Wir haben in spring.factories definiert:
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
com.example.demo.configuration.HelloWorldAutoConfiguration

Wir verwenden @EnableAutoConfigurationAnmerkungen für die Testklasse. Diese wird dann HelloWorldAutoConfigurationbis zum Frühjahr gescannt, um festzustellen, ob sie den Anforderungen entspricht. Wenn sie die Anforderungen erfüllt, wird sie in den IOC-Container aufgenommen.

  • HelloWorldAutoConfigurationDie Funktion der @ConditionalOnPropertyobigen Annotation lautet: Wenn helloworld=truediese Klasse in der Konfigurationsdatei konfiguriert wurde (wir haben diese Konfiguration hinzugefügt, damit sie den Anforderungen entspricht), erfüllt sie die Scanregeln. Die @EnableHelloWorldAnnotation ist eine benutzerdefinierte modulgesteuerte Annotation in unserem vorherigen Beispiel führt die Hallo-Bohne ein, sodass die Hallo-Bohne im IOC-Container vorhanden ist;

  • Durch die obigen Schritte können wir die Hallo-Bohne durch den Kontext bekommen.

 

Ich denke du magst

Origin blog.csdn.net/u014225733/article/details/100836544
Empfohlen
Rangfolge