


So rufen Sie ApplicationContextInitializer zurück, bevor der SpringBoot-Container aktualisiert wird
I. Projektvorbereitung
Das in diesem Artikel erstellte Beispielprojekt wurde mit SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ idea
entwickelt >SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ idea
进行开发
具体的SpringBoot项目工程创建就不赘述了,核心的pom文件,无需额外的依赖
配置文件 application.yml
, 也没有什么特殊的配置
II. 容器刷新前扩展点实例
1. 自定义ApplicationContextInitializer
当我们希望实现一个自定义的上下文初始化时,非常简单,实现上面这个接口就行了,如
public class ApplicationContextInitializer01 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer01"); } }
2. 扩展点注册
上面自定义一个扩展点,如何使它生效呢?
官方提供了三种方式,如在启动时,直接进行注册: springApplication.addInitializers(new ApplicationContextInitializer01());
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addInitializers(new ApplicationContextInitializer01()); try (ConfigurableApplicationContext context = springApplication.run(args)) { } } }
当我们的扩展点是放在一个jar包中对外提供时,使用上面的启动注册方式显然是不可行的,此时更推荐的做法就是通过Spring的SPI机制进行注册
在资源目录下的META-INF/spring.factories
文件中进行注册
org.springframework.context.ApplicationContextInitializer=com.git.hui.extention.context.ApplicationContextInitializer02
说明
上面SPI的机制非常推荐大家使用,在之前的文章中,
AutoConfiguration
的注册通常也是使用这种方式
除了上面的两种注册方式之外,另外还有一个配置文件的方式,在配置文件application.properties
或 application.yml
中,如下配置
context: initializer: classes: com.git.hui.extention.context.ApplicationContextInitializer03
启动测试
上面三种注册方式,我们实现三个自定义的扩展点,然后启动之后,看一下实际输出
上面的输出,可以简单的得出一个结论,不同注册方式的优先级(为了更合理的验证下面的观点,推荐大家修改下上面三个自定义扩展点名,排除掉是因为扩展名导致的排序问题)
配置文件注册 > SPI注册 > 启动时注册
3. 执行顺序指定
对于自定义的扩展点实现,当存在顺序关系时,我们可以通过@Order
注解来实现, 如当上面的三个扩展点都是通过启动方式注册时
@Order(5) public class ApplicationContextInitializer01 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer01"); } } @Order(2) public class ApplicationContextInitializer02 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer02"); } } @Order(10) public class ApplicationContextInitializer03 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer03"); } } @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addInitializers(new ApplicationContextInitializer01(), new ApplicationContextInitializer02(), new ApplicationContextInitializer03()); try (ConfigurableApplicationContext context = springApplication.run(args)) { } } }
输出实例如下
接着重点来了
若上面的三个自定义实现,不是相同的注册方式,如将03采用配置文件方式进行注册,那么01, 02 依然是启动注册
则顺序是 03 > 02 > 01
即
@Order
注解修饰的顺序,并不能打破 配置文件 > SPI > 启动方式注册的顺序
关于自定义实现类的执行顺序,规则如下
配置文件 > SPI > 启动方式
相同的注册方式,可以通过
@Order
注解进行修饰,值越小则优先级越高
4. 使用场景示例
最后我们再来看一下,这个扩展点到底有什么用,我们再什么场景下会用到这个呢?
一个经常可以看到的应用场景如通过它来指定需要激活的配置文件
public class ApplicationContextInitializer03 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { // 指定激活prod对应的配置文件 configurableApplicationContext.getEnvironment().setActiveProfiles("prod"); } }
但是一般也很少见到有人这么干,因为直接使用配置参数就行了,那么有场景需要这么做么?
答案当然是有的,比如现在广为流行的docker容器部署,当我们希望每次都是打同一个镜像,然后在实际运行的时候,根据不同的环境来决定当前镜像到底启用哪些配置文件,这时就有用了
比如我们通过容器的环境参数 app.env
来获取当前运行的环境,如果是prod,则激活application-prod.yml
; 如果是test,则激活application-test.yml
application.yml
und es gibt keine spezielle Konfiguration. Erweiterung vor der Containeraktualisierung Klicken Sie auf das Beispiel 1. Benutzerdefinierter ApplicationContextInitializer
Wenn wir eine benutzerdefinierte Kontextinitialisierung implementieren möchten, ist es sehr einfach, einfach die obige Schnittstelle zu implementieren, z. B. 🎜public class EenvActiveApplicationContextInitializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { String env = System.getenv("app.env"); if ("prod".equalsIgnoreCase(env)) { configurableApplicationContext.getEnvironment().setActiveProfiles("prod"); } else if ("test".equalsIgnoreCase(env)) { configurableApplicationContext.getEnvironment().setActiveProfiles("test"); } else { throw new RuntimeException("非法的环境参数:" + env); } } }
2 . Erweiterungspunktregistrierung🎜Wie kann ich einen Erweiterungspunkt oben anpassen und wirksam machen? 🎜🎜Offiziell bietet es drei Möglichkeiten, z. B. die direkte Registrierung beim Start: springApplication.addInitializers(new ApplicationContextInitializer01());
🎜rrreee🎜Wenn unser Erweiterungspunkt in einem JAR-Paket platziert wird Wenn externe Dienste bereitgestellt werden, ist dies der Fall Die Verwendung der oben genannten Startregistrierungsmethode ist derzeit offensichtlich nicht möglich. Die empfohlene Methode besteht darin, sich über den SPI-Mechanismus von Spring zu registrieren🎜🎜META-INF/spring.factories
im Ressourcenverzeichnis Datei🎜rrreee🎜Anweisungen🎜- 🎜Der obige SPI-Mechanismus wird jedem dringend empfohlen. Im vorherigen Artikel
AutoConfiguration
wird normalerweise auf diese Weise registriert🎜
🎜Zusätzlich zu den beiden oben genannten Registrierungsmethoden gibt es auch eine Konfigurationsdateimethode in der Konfigurationsdatei application .properties
oder application.yml
, konfigurieren Sie Folgendes: 🎜rrreee🎜Test starten🎜🎜Für die oben genannten drei Registrierungsmethoden implementieren wir drei benutzerdefinierte Erweiterungspunkte und nehmen sie dann nach dem Start Schauen Sie sich die tatsächliche Ausgabe an Container " />🎜🎜Die obige Ausgabe kann leicht eine Schlussfolgerung ziehen, die Priorität verschiedener Registrierungsmethoden (um den folgenden Standpunkt vernünftiger zu überprüfen, wird empfohlen, die oben genannten drei benutzerdefinierten Erweiterungen zu ändern und sie aus diesem Grund auszuschließen das durch den Namen verursachte Sortierproblem)🎜- 🎜Registrierung der Konfigurationsdatei> Registrierung beim Start🎜
3 Sequenzspezifikation
🎜Wenn bei der Implementierung eines benutzerdefinierten Erweiterungspunkts eine Sequenzbeziehung besteht, können wir diese über die Annotation @Order
implementieren. Wenn beispielsweise alle oben genannten drei Erweiterungspunkte gestartet werden Bei der Registrierung lautet das Ausgabebeispiel wie folgt: ApplicationContextInitializer vor dem Aktualisieren des SpringBoot-Containers" />🎜🎜Dann kommt der entscheidende Punkt🎜
- 🎜Wenn die oben genannten drei benutzerdefinierten Implementierungen nicht identisch sind Registrierungsmethode, z. B. 03. Wenn Sie die Konfigurationsdateimethode zur Registrierung verwenden, beginnen 01 und 02 weiterhin mit der Registrierung🎜
- 🎜Die Reihenfolge ist 03 > 01🎜
- 🎜Das heißt,
@OrderDie Reihenfolge der Anmerkungsänderung kann die Reihenfolge der <strong>Konfigurationsdatei>-Registrierung</strong> nicht aufheben die Ausführungsreihenfolge und Regeln benutzerdefinierter Implementierungsklassen wie folgt🎜<ul class=" list-paddingleft-2">
<li>🎜Konfigurationsdatei>Startup-Methode🎜</li>
<li>🎜Die gleiche Registrierungsmethode kann Zur Änderung wird die Annotation <code>@Order code> übergeben. Je kleiner der Wert, desto höher die Priorität Schauen Sie sich die Verwendung dieses Erweiterungspunkts an. In welchen Szenarien werden wir ihn verwenden? 🎜🎜Ein häufig vorkommendes Anwendungsszenario besteht darin, die zu aktivierende Konfigurationsdatei anzugeben. 🎜rrreee🎜Aber im Allgemeinen sieht man dies selten, da es ausreicht, die Konfigurationsparameter direkt zu verwenden. Gibt es also welche? Szenarien, in denen dies notwendig ist? 🎜🎜Die Antwort lautet natürlich: Ja. Wenn wir beispielsweise bei der mittlerweile weit verbreiteten Docker-Container-Bereitstellung jedes Mal das gleiche Image erstellen möchten, können wir dann während des tatsächlichen Betriebs entscheiden, welche Konfigurationsdateien im aktuellen Image aktiviert sind Je nach Umgebung ist dies nützlich. Beispielsweise verwenden wir den Umgebungsparameter des Containers <code>app.env
, um die aktuelle laufende Umgebung abzurufen. Wenn es sich um ein Produkt handelt, aktivieren Sie application-. prod.yml
; Wenn es sich um einen Test handelt, aktivieren Sie application-test.yml
🎜🎜Dann können Sie dies jetzt tun🎜rrreee
AutoConfiguration
wird normalerweise auf diese Weise registriert🎜@OrderDie Reihenfolge der Anmerkungsänderung kann die Reihenfolge der <strong>Konfigurationsdatei>-Registrierung</strong> nicht aufheben die Ausführungsreihenfolge und Regeln benutzerdefinierter Implementierungsklassen wie folgt🎜<ul class=" list-paddingleft-2">
<li>🎜Konfigurationsdatei>Startup-Methode🎜</li>
<li>🎜Die gleiche Registrierungsmethode kann Zur Änderung wird die Annotation <code>@Order code> übergeben. Je kleiner der Wert, desto höher die Priorität Schauen Sie sich die Verwendung dieses Erweiterungspunkts an. In welchen Szenarien werden wir ihn verwenden? 🎜🎜Ein häufig vorkommendes Anwendungsszenario besteht darin, die zu aktivierende Konfigurationsdatei anzugeben. 🎜rrreee🎜Aber im Allgemeinen sieht man dies selten, da es ausreicht, die Konfigurationsparameter direkt zu verwenden. Gibt es also welche? Szenarien, in denen dies notwendig ist? 🎜🎜Die Antwort lautet natürlich: Ja. Wenn wir beispielsweise bei der mittlerweile weit verbreiteten Docker-Container-Bereitstellung jedes Mal das gleiche Image erstellen möchten, können wir dann während des tatsächlichen Betriebs entscheiden, welche Konfigurationsdateien im aktuellen Image aktiviert sind Je nach Umgebung ist dies nützlich. Beispielsweise verwenden wir den Umgebungsparameter des Containers <code>app.env
, um die aktuelle laufende Umgebung abzurufen. Wenn es sich um ein Produkt handelt, aktivieren Sie application-. prod.yml
; Wenn es sich um einen Test handelt, aktivieren Sie application-test.yml
🎜🎜Dann können Sie dies jetzt tun🎜rrreee
Das obige ist der detaillierte Inhalt vonSo rufen Sie ApplicationContextInitializer zurück, bevor der SpringBoot-Container aktualisiert wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Einführung in Jasypt Jasypt ist eine Java-Bibliothek, die es einem Entwickler ermöglicht, seinem Projekt mit minimalem Aufwand grundlegende Verschlüsselungsfunktionen hinzuzufügen und kein tiefes Verständnis der Funktionsweise der Verschlüsselung erfordert. standardbasierte Verschlüsselungstechnologie. Passwörter, Text, Zahlen, Binärdateien verschlüsseln ... Geeignet für die Integration in Spring-basierte Anwendungen, offene API, zur Verwendung mit jedem JCE-Anbieter ... Fügen Sie die folgende Abhängigkeit hinzu: com.github.ulisesbocchiojasypt-spring-boot-starter2 Die Vorteile von Jasypt schützen unsere Systemsicherheit. Selbst wenn der Code durchgesickert ist, kann die Datenquelle garantiert werden.

Nutzungsszenario 1. Die Bestellung wurde erfolgreich aufgegeben, die Zahlung erfolgte jedoch nicht innerhalb von 30 Minuten. Die Zahlung ist abgelaufen und die Bestellung wurde automatisch storniert. 2. Die Bestellung wurde unterzeichnet und es wurde 7 Tage lang keine Bewertung durchgeführt. Wenn die Bestellung abläuft und nicht ausgewertet wird, wird die Bestellung standardmäßig positiv bewertet. Wenn der Händler die Bestellung innerhalb von 5 Minuten nicht erhält, wird die Bestellung abgebrochen Es wird eine SMS-Erinnerung gesendet ... Für Szenarien mit langen Verzögerungen und geringer Echtzeitleistung können wir die Aufgabenplanung verwenden, um eine regelmäßige Abfrageverarbeitung durchzuführen. Zum Beispiel: xxl-job Heute werden wir auswählen

1. Redis implementiert das Prinzip der verteilten Sperren und warum verteilte Sperren erforderlich sind. Bevor über verteilte Sperren gesprochen wird, muss erläutert werden, warum verteilte Sperren erforderlich sind. Das Gegenteil von verteilten Sperren sind eigenständige Sperren. Wenn wir Multithread-Programme schreiben, vermeiden wir Datenprobleme, die durch den gleichzeitigen Betrieb einer gemeinsam genutzten Variablen verursacht werden. Normalerweise verwenden wir eine Sperre, um die Richtigkeit der gemeinsam genutzten Variablen sicherzustellen Die gemeinsam genutzten Variablen liegen im gleichen Prozess. Wenn es mehrere Prozesse gibt, die gleichzeitig eine gemeinsam genutzte Ressource betreiben müssen, wie können sie sich dann gegenseitig ausschließen? Heutige Geschäftsanwendungen sind in der Regel Microservice-Architekturen, was auch bedeutet, dass eine Anwendung mehrere Prozesse bereitstellen muss. Wenn mehrere Prozesse dieselbe Datensatzzeile in MySQL ändern müssen, ist eine Verteilung erforderlich, um fehlerhafte Daten zu vermeiden wird zu diesem Zeitpunkt eingeführt. Der Stil ist gesperrt. Punkte erreichen wollen

Springboot liest die Datei, kann aber nach dem Packen in ein JAR-Paket nicht auf die neueste Entwicklung zugreifen. Es gibt eine Situation, in der Springboot die Datei nach dem Packen in ein JAR-Paket nicht lesen kann ist ungültig und kann nur über den Stream gelesen werden. Die Datei befindet sich unter resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

Wenn Springboot + Mybatis-plus keine SQL-Anweisungen zum Hinzufügen mehrerer Tabellen verwendet, werden die Probleme, auf die ich gestoßen bin, durch die Simulation des Denkens in der Testumgebung zerlegt: Erstellen Sie ein BrandDTO-Objekt mit Parametern, um die Übergabe von Parametern an den Hintergrund zu simulieren dass es äußerst schwierig ist, Multi-Table-Operationen in Mybatis-plus durchzuführen. Wenn Sie keine Tools wie Mybatis-plus-join verwenden, können Sie nur die entsprechende Mapper.xml-Datei konfigurieren und die stinkende und lange ResultMap konfigurieren Schreiben Sie die entsprechende SQL-Anweisung. Obwohl diese Methode umständlich erscheint, ist sie äußerst flexibel und ermöglicht es uns

SpringBoot und SpringMVC sind beide häufig verwendete Frameworks in der Java-Entwicklung, es gibt jedoch einige offensichtliche Unterschiede zwischen ihnen. In diesem Artikel werden die Funktionen und Verwendungsmöglichkeiten dieser beiden Frameworks untersucht und ihre Unterschiede verglichen. Lassen Sie uns zunächst etwas über SpringBoot lernen. SpringBoot wurde vom Pivotal-Team entwickelt, um die Erstellung und Bereitstellung von Anwendungen auf Basis des Spring-Frameworks zu vereinfachen. Es bietet eine schnelle und einfache Möglichkeit, eigenständige, ausführbare Dateien zu erstellen

1. Passen Sie den RedisTemplate1.1-Standard-Serialisierungsmechanismus an. Die API-basierte Redis-Cache-Implementierung verwendet die RedisTemplate-Vorlage für Daten-Caching-Vorgänge. Öffnen Sie hier die RedisTemplate-Klasse und zeigen Sie die Quellcodeinformationen der Klasse publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations an. Schlüssel deklarieren, verschiedene Serialisierungsmethoden des Werts, der Anfangswert ist leer @NullableprivateRedisSe

In Projekten werden häufig einige Konfigurationsinformationen benötigt. Diese Informationen können in der Testumgebung und in der Produktionsumgebung unterschiedliche Konfigurationen haben und müssen möglicherweise später basierend auf den tatsächlichen Geschäftsbedingungen geändert werden. Wir können diese Konfigurationen nicht fest im Code codieren. Am besten schreiben Sie sie in die Konfigurationsdatei. Sie können diese Informationen beispielsweise in die Datei application.yml schreiben. Wie erhält oder verwendet man diese Adresse im Code? Es gibt 2 Methoden. Methode 1: Wir können den Wert, der dem Schlüssel in der Konfigurationsdatei (application.yml) entspricht, über den mit @Value versehenen Wert erhalten. Diese Methode eignet sich für Situationen, in denen es relativ wenige Mikrodienste gibt: Tatsächlich Projekte, wenn das Geschäft kompliziert ist, Logik
