Erstellen eines benutzerdefinierten Starters mit Spring Boot

Erstellen eines benutzerdefinierten Starters mit Spring Boot

1. Überblick

Die Kernentwickler vonSpring Boottellenstarters für die meisten gängigen Open Source-Projekte bereit, aber wir sind nicht auf diese beschränkt.

We can also write our own custom starters. Wenn wir eine interne Bibliothek zur Verwendung in unserer Organisation haben, empfiehlt es sich, auch einen Starter dafür zu schreiben, wenn diese im Spring Boot-Kontext verwendet werden soll.

Diese Starter ermöglichen Entwicklern, langwierige Konfigurationen zu vermeiden und ihre Entwicklung schnell zu starten. Da jedoch viele Dinge im Hintergrund geschehen, wird es manchmal schwierig zu verstehen, wie eine Annotation oder nur das Einfügen einer Abhängigkeit inpom.xml so viele Funktionen ermöglicht.

In diesem Artikel entmystifizieren wir die Spring Boot-Magie, um zu sehen, was sich hinter den Kulissen abspielt. Dann werden wir diese Konzepte verwenden, um einen Starter für unsere eigene benutzerdefinierte Bibliothek zu erstellen.

2. Entmystifizierung der Autokonfiguration von Spring Boot

2.1. Automatische Konfigurationsklassen

Beim Start von Spring Boot wird im Klassenpfad nach einer Datei mit dem Namenspring.factories gesucht. Diese Datei befindet sich im VerzeichnisMETA-INF. Schauen wir uns einen Ausschnitt aus diesemfile from the spring-boot-autoconfigure-Projekt an:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

Diese Datei ordnet verschiedenen Konfigurationsklassen einen Namen zu, die Spring Boot auszuführen versucht. In diesem Snippet wird Spring Boot versuchen, alle Konfigurationsklassen für RabbitMQ, Cassandra, MongoDB und Hibernate auszuführen.

Ob diese Klassen tatsächlich ausgeführt werden, hängt vom Vorhandensein abhängiger Klassen im Klassenpfad ab. Wenn beispielsweise die Klassen für MongoDB im Klassenpfad gefunden werden, wirdMongoAutoConfiguration ausgeführt und alle mongo-bezogenen Beans werden initialisiert.

Diese bedingte Initialisierung wird durch die Annotation@ConditionalOnClassaktiviert. Schauen wir uns das Code-Snippet aus der Klasse vonMongoAutoConfigurationan, um seine Verwendung zu sehen:

@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoProperties.class)
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration {
    // configuration code
}

Wie nun - wennMongoClient im Klassenpfad verfügbar ist - wird diese Konfigurationsklasse ausgeführt, indem die Spring Bean-Factory mit einemMongoClient gefüllt wird, das mit den Standardkonfigurationseinstellungen initialisiert wurde.

2.2. Benutzerdefinierte Eigenschaften aus derapplication.properties-Datei

Spring Boot initialisiert die Beans mit einigen vorkonfigurierten Standardeinstellungen. Um diese Standardeinstellungen zu überschreiben, deklarieren wir sie im Allgemeinen in derapplication.properties-Datei mit einem bestimmten Namen. Diese Eigenschaften werden automatisch vom Spring Boot-Container übernommen.

Mal sehen, wie das funktioniert.

Im Code-Snippet fürMongoAutoConfiguration wird die Annotation@EnableConfigurationProperties mit der KlasseMongoPropertiesde deklariert, die als Container für benutzerdefinierte Eigenschaften fungiert:

@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {

    private String host;

    // other fields with standard getters and setters
}

Das Präfix und der Feldname geben die Namen der Eigenschaften in der Dateiapplication.propertiesan. Um diehost für MongoDB festzulegen, müssen wir nur Folgendes in die Eigenschaftendatei schreiben:

spring.data.mongodb.host = localhost

Ebenso können Werte für andere Felder in der Klasse mithilfe der Eigenschaftendatei festgelegt werden.

3. Erstellen eines benutzerdefinierten Starters

Basierend auf den Konzepten in Abschnitt 2 müssen zum Erstellen eines benutzerdefinierten Starters die folgenden Komponenten geschrieben werden:

  1. Eine Auto-Configure-Klasse für unsere Bibliothek sowie eine Properties-Klasse für die benutzerdefinierte Konfiguration.

  2. Ein Starterpom, um die Abhängigkeiten der Bibliothek und des Autokonfigurationsprojekts einzubringen.

Zur Demonstration haben wir einsimple greeting library erstellt, das eine Begrüßungsnachricht für verschiedene Tageszeiten als Konfigurationsparameter aufnimmt und die Begrüßungsnachricht ausgibt. Wir werden auch eine Spring Boot-Beispielanwendung erstellen, um die Verwendung unserer Autokonfigurations- und Startermodule zu demonstrieren.

3.1. Das Autokonfigurationsmodul

Wir nennen unser Auto-Konfigurationsmodulgreeter-spring-boot-autoconfigure. Dieses Modul wird zwei Hauptklassen haben, d.h. GreeterProperties, mit dem benutzerdefinierte Eigenschaften über die Dateiapplication.properties festgelegt werden können, undGreeterAutoConfiguartion, mit denen die Beans für die Bibliothekgreetererstellt werden.

Schauen wir uns den Code für beide Klassen an:

@ConfigurationProperties(prefix = "example.greeter")
public class GreeterProperties {

    private String userName;
    private String morningMessage;
    private String afternoonMessage;
    private String eveningMessage;
    private String nightMessage;

    // standard getters and setters

}
@Configuration
@ConditionalOnClass(Greeter.class)
@EnableConfigurationProperties(GreeterProperties.class)
public class GreeterAutoConfiguration {

    @Autowired
    private GreeterProperties greeterProperties;

    @Bean
    @ConditionalOnMissingBean
    public GreetingConfig greeterConfig() {

        String userName = greeterProperties.getUserName() == null
          ? System.getProperty("user.name")
          : greeterProperties.getUserName();

        // ..

        GreetingConfig greetingConfig = new GreetingConfig();
        greetingConfig.put(USER_NAME, userName);
        // ...
        return greetingConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public Greeter greeter(GreetingConfig greetingConfig) {
        return new Greeter(greetingConfig);
    }
}

Wir müssen auch einespring.factories-Datei imsrc/main/resources/META-INF-Verzeichnis mit folgendem Inhalt hinzufügen:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.example.greeter.autoconfigure.GreeterAutoConfiguration

Beim Start der Anwendung wird die KlasseGreeterAutoConfigurationausgeführt, wenn die KlasseGreeter im Klassenpfad vorhanden ist. Bei erfolgreicher Ausführung wird der Spring-Anwendungskontext mitGreeterConfig undGreeter Beans gefüllt, indem die Eigenschaften über dieGreeterProperties-Klasse gelesen werden.

Die Annotation@ConditionalOnMissingBeantellt sicher, dass diese Beans nur erstellt werden, wenn sie noch nicht vorhanden sind. Auf diese Weise können Entwickler die automatisch konfigurierten Beans vollständig überschreiben, indem sie ihre eigenen in einer der@Configuration-Klassen definieren.

3.2. pom.xml erstellen

Erstellen wir nun den Starterpom, der die Abhängigkeiten für das Auto-Configure-Modul und die Greeter-Bibliothek einbringt.

Gemäß der Namenskonvention sollten alle Starter, die nicht vom Spring Boot-Kernteam verwaltet werden, mit dem Bibliotheksnamen beginnen, gefolgt vom Suffix-spring-boot-starter. Also werden wir unseren Starter alsgreeter-spring-boot-starter: bezeichnen


    4.0.0

    com.example
    greeter-spring-boot-starter
    0.0.1-SNAPSHOT

    
        UTF-8
        0.0.1-SNAPSHOT
        1.5.2.RELEASE
    

    

        
            org.springframework.boot
            spring-boot-starter
            ${spring-boot.version}
        

        
            com.example
            greeter-spring-boot-autoconfigure
            ${project.version}
        

        
            com.example
            greeter
            ${greeter.version}
        

    

3.3. Den Starter benutzen

Erstellen wirgreeter-spring-boot-sample-app, die den Starter verwenden. Inpom.xml müssen wir es als Abhängigkeit hinzufügen:


    com.example
    greeter-spring-boot-starter
    ${greeter-starter.version}

Spring Boot konfiguriert automatisch alles und wir haben eineGreeter Bean bereit, die injiziert und verwendet werden kann.

Ändern Sie auch einige der Standardwerte vonGreeterProperties, indem Sie sie in der Dateiapplication.properties mit dem Präfixexample.greeterdefinieren:

example.greeter.userName=example
example.greeter.afternoonMessage=Woha\ Afternoon

Verwenden wir abschließend dieGreeter-Bean in unserer Anwendung:

@SpringBootApplication
public class GreeterSampleApplication implements CommandLineRunner {

    @Autowired
    private Greeter greeter;

    public static void main(String[] args) {
        SpringApplication.run(GreeterSampleApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        String message = greeter.greet();
        System.out.println(message);
    }
}

4. Fazit

In diesem kurzen Lernprogramm haben wir uns darauf konzentriert, einen benutzerdefinierten Spring Boot-Starter bereitzustellen und zu erläutern, wie diese Starter zusammen mit dem automatischen Konfigurationsmechanismus im Hintergrund funktionieren, um viele manuelle Konfigurationen zu vermeiden.

Der vollständige Quellcode für alle Module, die wir in diesem Artikel erstellt haben, finden Sie inover on GitHub.