SpringBoot自動アセンブリ-@条件付き条件付きアセンブリとカスタムスターター
1. @ Conditional
@Conditionalは、主に自動アセンブリの条件付き制約を提供するために使用され、通常は@Configurationおよび@Beanと組み合わせて使用されます。
1.1@Conditional
その構造を最初に見てください:
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
アノテーションが条件タイプの配列を受け取ることができることがわかります。Conditionは、主にmatchesメソッドを提供するために使用される機能インターフェイスです。**は条件付きマッチングルールを提供し、Beanを注入できることを示すためにtrueを返します。それ以外の場合は、注入されません。
****
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
ケース1:@Conditionalが条件付きアセンブリを実現
カスタム条件:
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String os = conditionContext.getEnvironment().getProperty("os.name");
// 如果电脑运行环境是Mac,那么返回true
// 如果你的电脑是window,这里输入Windows
if (os.contains("Mac OS X")) {
return true;
}
return false;
}
}
カスタム構成クラス:
@Configuration
public class ConditionConfig {
@Conditional(MyCondition.class)
@Bean
// 只有MyCondition返回true时,这里才会加载这个Bean
public FirstBean getBean(){
return new FirstBean();
}
}
スタートアップクラス:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
// FirstBean是我自定义的Bean
FirstBean bean = context.getBean(FirstBean.class);
System.out.println(bean.toString());
}
}
結果:
この時点で、環境がWindowの場合にtrueを返すなど、ロジックを変更すると、結果は次のようなエラーを報告します。
1.2SpringBootの@Conditional
SpringBootでは、@ Conditionalが展開されています。展開されたアノテーションは次のとおりです。
- ConditionalOnBean / ConditionalMissingBean:Beanのロードは、特定のクラスまたはBeanがコンテナーに存在しない場合に実行されます。
- ConditionalOnClass / ConditionalMissingClass:Beanのロードは、指定されたクラスがクラスパスに存在する場合、または存在しない場合に実行されます。
- ConditionalOnCloudPlatForm:指定されたクラウドプラットフォームで実行されている場合にのみ、指定されたBeanをロードします。
- ConditionalOnExpression:spEL式に基づく条件付き判断。
- ConditionalOnJava:Beanは、指定されたバージョンのJavaが実行されている場合にのみロードされます。
- ConditionalOnJndi:指定されたリソースがJNDIを介してロードされた後にのみ、Beanをロードします。
- ConditionalOnWebApplication / ConditionalOnNotWebApplication:Webアプリケーションであるかどうかに関係なく、Beanをロードします。
- ConditionalOnProperty:システムで指定された対応するプロパティに対応する値があるかどうかに関係なく、Beanがロードされます。
- ConditionalOnResource:ロードされるBeanは、指定されたリソースがクラスパスに存在するかどうかによって異なります。
- ConditionalOnSingleCandidate:Beanは、特定のBeanクラスの単一の候補が決定された場合にのみロードされます。
これらのアノテーションは、@ Configuration構成クラスのクラスレベルまたはメソッドレベルに追加するだけでよく、各アノテーションの役割に応じてパラメーターを渡すことができます。
ケース2:@条件付き拡張子
ConditionalOnProperty:
- このクラスは、application.propertiesまたはapplication.ymlファイルでtest.bean.enble = trueの場合にのみロードされます
- 一致するものがない場合は、matchIfMissing = true(デフォルトはfalse)であるため、ロードされます。
@Configuration
@ConditionalOnProperty(value = "test.bean.enble", havingValue = "true", matchIfMissing = true)
public class ConditionConfig {
}
ConditionalOnBean:
- FirstBeanクラスのみがコンテナに存在し、ConditionConfigがアセンブルされます
@Configuration
@ConditionalOnBean(FirstBean.class)
public class ConditionConfig {
}
ConditionalOnResource:
- test.propertiesファイルがクラスパスに存在する場合、ConditionConfigが自動的にロードされます。
@Configuration
@ConditionalOnResource(resources = "/test.properties")
public class ConditionConfig {
}
1.3spring-autoconfigure-メタデータ
@Conditionalアノテーションクラスに加えて、Spring-autoconfigure-metadata.propertiesファイルもSpringBootで提供され、バッチ自動アセンブリの条件付き構成を実現します。
これらの条件構成が構成ファイルに配置されることを除いて、@ Conditionalと同じように機能します。同時に、この構成方法で条件付きフィルタリングを実装するには、次の2つの条件に従う必要があります。
- 構成ファイルのパスと名前は/META-INF/spring-autoconfigure-metadata.propertiesである必要があります
- 構成ファイル内のキーの形式:自動構成クラスの絶対パス名。Condition= value
利点:
- SpringBootの起動時間を効果的に短縮できます。このフィルタリング方法により、設定クラスの読み込み回数を減らすことができます。このフィルタリングは設定クラスの読み込み前に行われるため、SpringBootの起動時にBeanの読み込みにかかる時間を短縮できます。
二. Starter
スターターコンポーネントには、次の3つの主要な機能があります。
- 関連するコンポーネントのJarパッケージの依存関係を含みます。
- Beanアセンブリの自動実現。
- application.propertiesファイルでプロパティ構成を自動的に宣言してロードします。
スターター命名規則:
- 正式な命名形式:spring-boot-starter-module name
- カスタム命名形式:モジュール名-春-ブート-スターター
ケース3:Redisに基づいてスターターをカスタマイズする
プロジェクト構造:
カスタム構成クラスRedisAutoConfiguration:
- 主にRedissonClientをIOCコンテナにアセンブルするために、自動的にアセンブルする必要がある構成クラスを定義します。
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Configuration
@ConditionalOnClass(Redisson.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedisAutoConfiguration {
RedissonClient redissonClient(RedissonProperties redissonProperties) {
Config config = new Config();
String prefix = "redis://";
if (redissonProperties.isSsl()) {
prefix = "rediss://";
}
SingleServerConfig singleServerConfig = config.useSingleServer().setAddress(prefix + redissonProperties.getHost() + ":" + redissonProperties.getPort())
.setConnectTimeout(redissonProperties.getTimeout());
if (!StringUtils.isEmpty(singleServerConfig)) {
singleServerConfig.setPassword(redissonProperties.getPassword());
}
return Redisson.create(config);
}
}
カスタム構成クラスRedissonProperties:
- プロパティクラスを定義し、application.propertiesでRedis接続パラメーターを構成します。
- @ConfigurationPropertieの機能は、現在のクラスのプロパティを構成ファイル(properties / yml)の構成にバインドすることであり、プレフィックスはmy.redissonです。
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "my.redisson")
public class RedissonProperties {
private String host="localhost";
private String password;
private int port=6379;
private int timeout;
private boolean ssl;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public boolean isSsl() {
return ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
}
spring.factories:
- 目的は、SpringBootプログラムがファイルをスキャンして自動アセンブリを完了することを可能にすることです。キーと値は次のとおりです。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.config.RedisAutoConfiguration
application.properties:
- プロパティ構成を設定します。
- このプロパティは、RedissonPropertiesで定義された対応するプロパティに自動的にバインドされます。
my.redission=192.168.237.130
my.redission.port=6379
pom:
- スターター依存関係を追加します(redis-spring-boot-starter)
<parent>
<groupId>org.springframework.boot</groupId>
<version>2.3.5.RELEASE</version>
<artifactId>spring-boot-starter-parent</artifactId>
</parent>
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
上記の手順を完了すると、簡単な手書きのスターターが完成します。