序章
Java 開発者にとって、Spring フレームワークはほぼ必須です。これは、エンタープライズ アプリケーションの開発に広く使用されているオープンソースの軽量フレームワークです。近年では、従来の Spring フレームワークをベースに、Spring のすべての機能を提供するだけでなく、開発者にとって使いやすい Spring Boot が登場しました。Spring Boot を使用するとき、さまざまな Spring Boot Starter に遭遇することがよくあります spring-boot-starter-web
。この依存関係をプロジェクトに追加するだけで、アプリケーションの開発を開始できます。インポート後 spring-boot-starter-data-jdbc
、データベースに接続するためのデータベース接続情報を構成ファイルに入力するだけです。さらに、ビジネス コードを変更せずに、データ ソース コンポーネントの依存関係を自由に切り替えることができます。Spring Boot Starter はどのように適応しますか? Spring Boot Starter を自分で実装できますか? この記事では、Spring Boot Starter の原理を分析し、カスタム Spring Boot Starter コンポーネントを実装します。
1. Spring Boot スターターとは何ですか?
Spring Boot Starter は Spring Boot の重要な概念であり、構成を簡素化するのに役立つ依存関係記述子です。Web アプリケーションを構築する必要がある場合、すべての依存パッケージを調べてプロジェクトの依存関係管理に 1 つずつ追加する必要はありません。次の例のように、必要な構成は 1 つだけです。 spring-boot-starter-web
上記の例から、かなり少量のコードで REST アプリケーションを作成しました。Spring では公式に多数のスターターが提供されており、サードパーティでもスターターをカスタマイズできますが、これらを区別するために、スターターは次のように標準化されています: ; サードパーティが提供するスターター名は次のとおりspring-boot-starter-xxx
ですxxx-spring-boot-starter
。
2. Spring Boot Starterの解析
Starter の概念と REST アプリケーションを迅速に作成する方法については前に紹介しました。REST インターフェイスの開発は、依存関係と数行のコードを追加するだけで実行できます。では、Spring Boot と Starter を使用せずにどうやって開発するのでしょうか? Spring Boot Starter はどのように機能しますか? 次に、例として Web サービスと Dubbo サービスを開発することで、純粋な Spring と Spring Boot Starter をそれぞれ分析します。
春
環境に依存する
-
JDK1.8
-
メイブン 3
-
Tomcat 8 (Web コンテナサーバーの起動が必要)
-
spring-webmvc 4.3.30.RELEASE
-
ダボ 2.7.23
開発プロセス
-
最初に紹介します。これは標準の Maven ディレクトリ構造と依存コンテンツです。
demo-service
<dependencies> <!-- SpringMVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.30.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!-- 此处需要导入databind包即可, jackson-annotations、jackson-core都不需要显示自己的导入了--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <!-- Dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.23</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-x-discovery</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.8.0</version> </dependency> <!-- Demo API --> <dependency> <groupId>com.demo</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
Spring XML で実行するには依然として Java Web と Web コンテナに依存する必要があるため、Web 構成ファイルも必要であり、コンテンツは SpringMVC エントリを構成します。
web/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- Spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo.xml</param-value> </context-param> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
SpringMVC設定ファイルとDubbo設定ファイル
mvc.xml
dubbo.xml
<?xml version="1.0" encoding="utf-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.demo.controller"/> <!-- 开启 MVC 注解驱动 --> <mvc:annotation-driven/> <!-- 访问静态资源 --> <mvc:default-servlet-handler/> </beans>
<?xml version="1.0" encoding="utf-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- Dubbo --> <dubbo:application name="demo-service"/> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <dubbo:protocol name="dubbo" port="20880"/> <bean id="demoServiceImpl" class="com.demo.provider.DemoServiceImpl"/> <dubbo:service interface="com.demo.api.DemoService" ref="demoServiceImpl"/> </beans>
-
書き込みコントローラー インターフェイスと Dubbo RPC インターフェイス
package com.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping(value = "/say/hello") public HelloEntity sayHello() { return new HelloEntity("Hello World"); } }
package com.demo.provider; import com.demo.api.DemoService; import com.demo.dto.HelloEntity; public class DemoServiceImpl implements DemoService { @Override public HelloEntity sayHello() { return new HelloEntity("Hello World"); } }
-
上記は独立して実行できません。実行するには、上記をパッケージ化してTomcat に入れる必要があります。
war
分析する
上記の開発プロセスから、入り口はすべて にあることがわかります web.xml
。リスナーとサーブレット、および初期化パラメータ dubbo.xml
と が ありますmvc.xml
。Spring Boot が登場する前は、Spring は通常、XML 設定を使用して Bean を記述するか、アノテーション駆動型およびコンテキスト スキャン メソッドを設定して XML 内の Bean を解析していました。したがって、ここには 2 つの XML ファイルがあることがわかります。ソースコードを解析した結果、XMLタグ解析からBean解析までの流れを以下のように整理しました。次のように:
-
Tomcat によってロードを開始し、Spring がリスナーとサーブレットを通じて XML をロードおよび解析できるようにします。
web.xml
-
カスタム タグが解析されるまで、 XML 名前空間が見つかるかタグが見つかります。
BeanDefinitionParserDelegate#parseCustomElement
mvc:xxx
dubbo:xxx
-
DefaultNamespaceHandlerResolver
処理ロジック: すべての jar を遅延読み込み方式(パスはこれである必要があります) でロードしてキャッシュし、名前空間 URI を通じて対応する処理クラスを見つけます。SpringMVC および Dubbo 名前空間処理クラスは次のとおりです。META-INF/spring.handlers
handlerMappings
MvcNamespaceHandler
DubboNamespaceHandler
-
MvcNamespaceHandler
と でそれぞれメソッドを実装しました。内容は次のとおりです。このメソッドはSpringMVC タグと Dubbo タグを対応して 登録します 。前のステップでは、 label に従ってラベルが取得され 、対応する Bean が Spring IOC コンテナに登録されました。登録ロジックはこの記事の焦点ではないため、ここでは繰り返しません。ここまでで SpringMVC と Dubbo のロード処理が完了しました。DubboNamespaceHandler
NamespaceHandler#init
init
BeanDefinitionParser
NamespaceHandlerSupport#parsers
DefaultNamespaceHandlerResolver
BeanDefinitionParser
上記の読み込みプロセスから、Spring Boot の前には Spring は主に XML 設定に依存して起動していたことがわかります。XML でカスタム タグをロードし、対応する名前空間を見つけて、クラスパスをスキャンして META-INF/spring.handlers
名前空間処理クラスを見つけ、現在のタグを解析します。
スプリングブーツ
環境に依存する
-
JDK1.8
-
メイブン 3
-
スプリングブート 2.6.9
-
ダボ 2.7.23
開発プロセス
-
ディレクトリ構造と Maven依存関係の内容
demo-spring-boot
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.23</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-x-discovery</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>com.demo</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
申請エントリー
DemoSpringBootApplication
@SpringBootApplication public class DemoSpringBootApplication { public static void main(String[] args) { SpringApplication.run(DemoSpringBootApplication.class, args); } }
-
application.yml
ファイルの内容はDubboの設定のみですdubbo: application: name: demo-provider protocol: port: 20880 name: dubbo registry: address: zookeeper://127.0.0.1:2181
-
書き込みコントローラー インターフェイスと Dubbo RPC インターフェイス
package com.demo.controller; import com.demo.dto.HelloEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping(value = "/say/hello") public HelloEntity sayHello() { return new HelloEntity("Hello World"); } }
package com.demo.provider; import com.demo.api.DemoService; import com.demo.dto.HelloEntity; @DubboService public class DemoServiceImpl implements DemoService { @Override public HelloEntity sayHello() { return new HelloEntity("Hello World"); } }
-
Tomcat が埋め込まれているため、メソッドを直接実行するだけでアプリケーションを実行できます。
spring-boot-starter-web
DemoSpringBootApplication#main
分析する
開発プロセスからは、最初に分析エントリを見つける方法はありません。唯一のエントリは にあります。ソース コード分析後、次のフローが得られます。 DemoSpringBootApplication
-
アプリケーションクラスにはアノテーションがあり、アノテーションは次の 3 つのアノテーションで構成されます。
DemoSpringBootApplication
@SpringBootApplication
-
@SpringBootConfiguration
、現在のクラスを構成クラスとしてマークします。これはアノテーション関数と一貫性があり、アノテーションが付けられたクラスは Spring の XML バージョンのコンテナーに対応します。@Configuration
@Configuration
-
@EnableAutoConfiguration
、自動配線を有効にするキーで、次で構成されます。@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
-
@ComponentScan
、現在のクラスパスに従って、などのアノテーションを含むクラスをスキャンします。これは Spring XML のものと同等です。@Service
@Controller
context:component-scan
-
-
Spring Boot はインポートされたクラスを自動アセンブルし、 ClassPath からすべての jar パッケージの内容をスキャンするように呼び出します。これは に渡されるため、キーの値のみを返し、完全修飾クラス名の文字列配列を取得します。
@EnableAutoConfiguration
AutoConfigurationImportSelector
SpringFactoriesLoader#loadFactoryNames
META-INF/spring.factories
EnableAutoConfiguration.class
org.springframework.boot.autoconfigure.EnableAutoConfiguration
configurations
-
configurations
重複排除と宣言的除外の後、次のフィルタリングと自動アセンブリが実行されます。configurations = getConfigurationClassFilter().filter(configurations)
フィルタの取得とフィルタリングの実行の 2 つの部分に分かれています。
-
getConfigurationClassFilter()
また、Key の値をSpringFactoriesLoader#loadFactoryNames
見つけることによって、現在フィルターは、、および の3 つだけです。META-INF/spring.factories
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter
OnBeanCondition
OnClassCondition
OnClassCondition
-
フィルタリングが実行されると、構成クラスの、、などを含む条件付きアノテーションに従って、一部の構成クラスがフィルタリングされます。たとえば、仕様を有効にするには、以下の。
@ConditionOnBean
@ConditionalOnClass
@ConditionalOnWebApplication
WebMvcAutoConfiguration
@ConditionOnWebApplication
-
-
さまざまな Configuration 構成クラスを導入した後、構成クラスを結合してSpring Bean の解析とインジェクションを完了すると同時に、Spring Boot は開発者向けに多くの柔軟なインジェクションも提供します。
@Bean
@ConditionalXXX
以上がSpring Bootの自動組み立て処理です。Spring Boot は、 @Configuration
Spring XML の代わりにアノテーション付き構成クラスを使用して Bean インジェクションを完了します。次に、SpringFactoriesLoader
最終ロード META-INF/spring.factories
の自動構成クラスを実装して、自動アセンブリプロセスを実現します。「合意は設定よりも重要である」という考えに基づいて、開発されたスターターを有効にしたい場合は、Spring Boot 合意に従う必要があります。
まとめ
Spring と Spring Boot の開発プロセスを比較すると、Web と Dubbo の独立したアプリケーション開発を完了するときに Spring Boot が使用するコードと構成が比較的少ないことがわかります。これは、Spring Boot の主要機能である Spring Boot Starter の自動配線機能のおかげです。自動構成は、自動構成の一部である一部のクラスを定義する必要性を排除することで、開発プロセスを簡素化し、スピードアップするのに役立ちます。
SPI
上記の分析から、どちらも、インポートされた jar パッケージ内の設定ファイルをロードして、対応するクラス、つまりSPI (Service Provider Interface)をロードするメカニズムを使用していることがわかりました。
SPI (Service Provider Interface) は、フレームワークのスケーラビリティを向上させる Java の組み込みサービス検出メカニズムです。
Java SPI
Java の組み込み SPI は、クラスパスおよび jar パッケージ ディレクトリの下にあるインターフェイスの完全修飾名で指定されたファイルをclass を通じて解析し、ファイル内で指定されたインターフェイス実装クラスをロードして呼び出しを完了します。 java.util.ServiceLoader
META-INF/services
ただし、Java SPI には次のような欠点があります。
-
オンデマンドの読み込みは実現できないため、すべての実装を走査してインスタンス化し、ループ内で必要な実装を見つける必要があります。
-
クラスのインスタンスを複数同時にマルチスレッドで使用する場合は安全ではありません
ServiceLoader
-
実装クラスをロードできない場合、本当の理由ではない例外がスローされ、エラーを特定するのが困難になります。
春のSPI
Spring SPIはJava SPIを踏襲していますが、Java SPIと実装に違いはありますが、コアの仕組みは同じであり、Springのソースコードを変更することなくSpringフレームワークの拡張開発を実現できます。
-
Spring XML では、 namespaceUri 名と NamespaceHandler 名のマッピングを解析して生成し、必要に応じてそれらをインスタンス化します。
DefaultNamespaceHandlerResolver
spring.handlers
-
Spring Boot では、ファイルを解析し、指定されたインターフェイスのすべての実装クラス/完全修飾クラス名を返す役割を果たします。
SpringFactoriesLoader
spring.factories
スプリングブート 2.7.0
この記事では、Spring Boot 自動アセンブリは SPI を使用して指定された自動アセンブリ クラス名にロードしますが、 Spring Boot 2.7.0以降、自動アセンブリ SPI メカニズムは変更され、破棄されます。コードは削除され、変更は次のようになります。 EnableAutoConfiguration
META-INF/spring.factories
-
新しい注釈:
@AutoConfiguration
の代わりに@Configuration
-
自動アセンブリを読み取るクラス ファイルの場所は次のように変更され
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
、実装クラスの完全修飾クラス名は一度に 1 行になります。 -
は解析を担当します。 はインターフェイス名のプレースホルダーです
org.springframework.boot.context.annotation.ImportCandidates#load
META-INF/spring/%s.imports
%s
3. Spring Boot Staterの実践
データベース操作を使用するとき、またはデータベース操作を待機するときに、通常、次のようなデータベース データ ソース接続プールが導入されます。同時に、ビジネス コードを変更せずに依存関係を自由に切り替えることができるため、開発者は次の点に注意を払う必要はありません。ここでは、Starter もこの互換性を実装します。なぜなら、私たちは分散ロックスターターを開発しており、Zookeeper、Redis などの複数の実装を持っているからです。ここでは Spring Boot 2.6.9 バージョンを使用します。 spring-boot-starter-jdbc
spring-boot-starter-jpa
HikariCP
DBCP
開発する
プロジェクトの構造と Maven の依存関係
└── src
├── main
│ ├── java
│ │ └── com.demo.distributed.lock
│ │ ├── api
│ │ │ ├── DistributedLock.java
│ │ │ └── LockInfo.java
│ │ ├── autoconfigure
│ │ │ ├── DistributedLockAutoConfiguration.java
│ │ │ └── DistributedLockProperties.java
│ │ ├── redis
│ │ │ └── RedisDistributedLockImpl.java
│ │ └── zookeeper
│ │ └── ZookeeperDistributedLockImpl.java
│ └── resources
│ └── META-INF
│ └── spring.factories
<dependencies>
<!-- Spring Boot 自动装配注解 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 生成 META-INF/spring-configuration-metadata.json -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Zookeeper -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.23.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
依存関係では、Zookeeper と Redis の依存関係がコンパイルとテストのフェーズで使用されるように設定されており、プロジェクトとともにリリースされないことがわかります。つまり、パッケージ化時に依存関係は持ち込まれません。この設定は Spring Boot Starter でより効果的です。 provided
分散ロックのインターフェイスと実装
インターフェース
public interface DistributedLock {
/**
* 加锁
*/
LockInfo tryLock(String key, long expire, long waitTime);
/**
* 释放锁
*/
boolean release(LockInfo lock);
}
Redisの実装
public class RedisDistributedLockImpl implements DistributedLock {
private final RedissonClient client;
public RedisDistributedLockImpl(RedissonClient client) {
this.client = client;
}
@Override
public LockInfo tryLock(String key, long expire, long waitTime) {
//do something
return null;
}
@Override
public boolean release(LockInfo lock) {
//do something
return true;
}
}
Zookeeperの実装
public class ZookeeperDistributedLockImpl implements DistributedLock {
private final CuratorFramework client;
public ZookeeperDistributedLockImpl(CuratorFramework client) {
this.client = client;
}
@Override
public LockInfo tryLock(String key, long expire, long waitTime) {
return null;
}
@Override
public boolean release(LockInfo lock) {
return false;
}
}
DistributedLockAutoConfiguration 構成クラス
@EnableConfigurationProperties(DistributedLockProperties.class)
@Import({DistributedLockAutoConfiguration.Zookeeper.class, DistributedLockAutoConfiguration.Redis.class})
public class DistributedLockAutoConfiguration {
@Configuration
@ConditionalOnClass(CuratorFramework.class)
@ConditionalOnMissingBean(DistributedLock.class)
@ConditionalOnProperty(name = "distributed.lock.type", havingValue = "zookeeper",
matchIfMissing = true)
static class Zookeeper {
@Bean
CuratorFramework curatorFramework(DistributedLockProperties properties) {
//build CuratorFramework client
return null;
}
@Bean
ZookeeperDistributedLockImpl zookeeperDistributedLock(CuratorFramework client) {
return new ZookeeperDistributedLockImpl(client);
}
}
@Configuration
@ConditionalOnClass(RedissonClient.class)
@ConditionalOnMissingBean(DistributedLock.class)
@ConditionalOnProperty(name = "distributed.lock.type", havingValue = "redis",
matchIfMissing = true)
static class Redis {
@Bean
RedissonClient redissonClient(DistributedLockProperties properties) {
//build RedissonClient client
return null;
}
@Bean
RedisDistributedLockImpl redisDistributedLock(RedissonClient client) {
return new RedisDistributedLockImpl(client);
}
}
}
-
@EnableConfigurationProperties(DistributedLockProperties.class)
構成クラスの「プロパティー」情報を開くと、構成ファイル内の情報がプロパティー・クラスに挿入されます。 -
@Configuration
設定メモ -
@ConditionalOnClass(CuratorFramework.class)
条件付きアノテーションを有効にするには、現在の構成クラスが存在する必要があり、Redis のサブ構成クラスは同じです。CuratorFramework
-
@ConditionalOnMissingBean(DistributedLock.class)
条件付きアノテーション、 Bean の現在の構成クラスはSpring に存在せず、Redis のサブ構成クラスは同じです。DistributedLock
-
@ConditionalOnProperty(name = "distributed.lock.type", havingValue = "zookeeper", matchIfMissing = true)
条件付きアノテーション、ここでは設定ファイルが有効であると判断し、設定されていない場合はデフォルトとみなされ、Redisのサブ設定クラスが同じになります。distributed.lock.type
zookeeper
zookeeper
-
@Bean
メソッドによって返された Bean を Spring IOC コンテナに注入します。メソッドの入力パラメータには依存する Bean が含まれます。
春の工場
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.demo.distributed.lock.autoconfigure.DistributedLockAutoConfiguration
ファイルを置くだけで、Spring Boot によってロードされます。これは、コントラクトが構成よりも大きいという Spring Boot の考え方でもあります。 resource/META-INF/spring.factories
使用
Maven の依存関係
<dependencies>
<dependency>
<groupId>com.demo</groupId>
<artifactId>distributed-lock-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<!-- Redis -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.23.1</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>test</id>
<dependencies>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</profile>
</profiles>
ここでは、Maven プロファイル機能がさまざまな環境と組み合わされて、分散ロックのさまざまな基盤となる実装に依存します。同時に、Spring Boot は、さまざまな構成をロードするための Spring Boot プロファイルも提供します。開発、テスト、およびさまざまな基盤となるレイヤーを使用できます。運用環境と同時に、Maven プロファイルを仕様に従ってロードできます。異なる環境で異なる分散ロック実装を使用する問題を解決するために、異なる依存関係がパッケージ化されています。 -P
コードの使用法
private final DistributedLock distributedLock;
public DemoServiceImpl(DistributedLock distributedLock) {
this.distributedLock = distributedLock;
}
public void test() {
LockInfo lock = null;
try {
lock = distributedLock.tryLock("demo", 1000, 1000);
//do something
} finally {
if (lock != null) {
distributedLock.release(lock);
}
}
}
ビジネス コードは Spring Boot Starter 条件付きアノテーション + Maven プロファイルと組み合わせたインターフェイスに依存しているため、どの分散ロック実装がそれに依存しているかに関係なく、コードを変更する必要はありません。
4. まとめ
この記事では、Spring Boot と Starter が登場する前は、従来の Spring XML を使用して Web アプリケーションを開発する場合、開発者は多くの依存関係を参照する必要があり、Bean とその依存関係を記述するために多くの XML コードを記述する必要があることを紹介します。また、SPI を使用してカスタム タグをロードし、Bean をロードして注入する方法も学習しました。@Configuration
Spring Boot Starter は、より最新の構成メソッドを提供します。このメソッドは、SPI メカニズムを通じて自動アセンブリ構成クラスをロードし、 従来の Spring XML を置き換えて Bean インジェクションを完了し、それによって多数の XML 構成を排除します。最後に、一連の @ConditionalXXX
アノテーションと Maven プロファイルを使用してカスタマイズして分散ロック Spring Boot Starter コンポーネントを開発し、開発を完了しました。このようにして、複数の分散ロック実装と互換性があり、ビジネス コードを変更することなく、異なる環境で異なる分散ロック実装を使用できます。
MyBatis-Flex の MyBatis-Plus 盗用に関する明確化 Chrome の代替品であると主張する Arc ブラウザ 1.0 が正式にリリース OpenAI が Android バージョンを正式にリリース ChatGPT VS Code で名前の難読化圧縮が最適化され、組み込み JS が 20% 削減されました。 LK-99: 最初の室温常圧超伝導体? マスク氏は「ゼロ元で購入」し、@x Twitter アカウントを強奪したPython 運営委員会は PEP 703 提案を受け入れる予定で、 グローバル インタープリタ ロックをオプションにする . システムのオープンソースで無料のパケット キャプチャ ソフトウェアへのアクセス数Stack Overflow大幅に下落し、マスク氏はLLMに取って代わられたと述べた著者: JD Retail 陳延青
出典: JD Cloud 開発者コミュニティ