SpringBoot 자동 어셈블리-@ 조건부 조건부 어셈블리 및 사용자 지정 스타터
1. @ 조건부
@Conditional은 주로 자동 어셈블리에 대한 조건부 제약을 제공하는 데 사용되며 일반적으로 @Configuration 및 @Bean과 함께 사용됩니다.
1.1 @ 조건부
먼저 구조를 살펴보십시오.
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
어노테이션이 Condition 유형의 배열을 수신 할 수 있음을 알 수 있습니다. Condition은 주로 match 메서드를 제공하는 데 사용되는 기능적 인터페이스입니다. ** 조건부 일치 규칙을 제공하고, 빈이 주입 될 수 있음을 나타 내기 위해 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.2 SpringBoot의 @Conditional
SpringBoot에서는 @Conditional이 확장되었으며 확장 된 주석은 다음과 같습니다.
- ConditionalOnBean / ConditionalMissingBean : 컨테이너에 특정 클래스가 있거나 Bean이없는 경우 Bean 로딩이 수행됩니다.
- ConditionalOnClass / ConditionalMissingClass : 지정된 클래스가 존재하거나 클래스 경로에 존재하지 않을 때 Bean 로딩이 수행됩니다.
- ConditionalOnCloudPlatForm : 지정된 클라우드 플랫폼에서 실행되는 경우에만 지정된 Bean을로드합니다.
- ConditionalOnExpression : spEL 표현에 기반한 조건부 판단.
- ConditionalOnJava : 지정된 버전의 Java가 실행 중일 때만 Bean이로드됩니다.
- ConditionalOnJndi : 지정된 자원이 JNDI를 통해로드 된 후에 만 Bean을로드합니다.
- ConditionalOnWebApplication / ConditionalOnNotWebApplication : 웹 응용 프로그램인지 아닌 경우 Bean을로드합니다.
- ConditionalOnProperty : 시스템에 지정된 해당 속성에 해당 값이 있는지 여부는 Bean이로드됩니다.
- ConditionalOnResource :로드 할 Bean은 지정된 리소스가 클래스 경로에 있는지 여부에 따라 다릅니다.
- ConditionalOnSingleCandidate : Bean은 주어진 Bean 클래스에 대한 단일 후보가 결정될 때만로드됩니다.
이러한 주석은 @Configuration 구성 클래스의 클래스 수준 또는 메서드 수준에만 추가하면되며 각 주석의 역할에 따라 매개 변수를 전달할 수 있습니다.
사례 2 : @Conditional 확장
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.3 spring-autoconfigure-metadata
@Conditional 주석 클래스 외에도 spring-autoconfigure-metadata.properties 파일도 SpringBoot 에서 제공되어 일괄 자동 어셈블리의 조건부 구성을 실현합니다.
이러한 조건 구성이 구성 파일에 배치된다는 점을 제외하면 @Conditional과 동일하게 작동합니다. 동시에이 구성 방법을 통해 조건부 필터링을 구현하려면 두 가지 조건을 따라야합니다.
- 구성 파일의 경로 및 이름은 /META-INF/spring-autoconfigure-metadata.properties 여야합니다.
- 구성 파일의 키 형식 : 자동 구성 클래스의 전체 경로 이름 Condition = value
이점:
- SpringBoot의 시작 시간을 효과적으로 줄일 수 있으며, 이러한 필터링 방식을 통해 구성 클래스의 로딩 수를 줄일 수 있으며, 이러한 필터링은 구성 클래스의 로딩 이전에 발생하기 때문에 SpringBoot 시작시 Beans 로딩 시간을 줄일 수있다.
두. Starter
Starter 구성 요소에는 세 가지 주요 기능이 있습니다.
- 관련 구성 요소의 Jar 패키지 종속성을 포함합니다.
- Bean 어셈블리 자동 실현.
- application.properties 파일에서 속성 구성을 자동으로 선언하고로드합니다.
스타터 명명 규칙 :
- 공식 이름 지정 형식 : spring-boot-starter-module name
- 사용자 지정 이름 지정 형식 : 모듈 이름 -spring-boot-starter
사례 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;
}
}
봄. 공장 :
- 목적은 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>
위의 단계를 완료하면 간단한 손으로 쓴 스타터가 완료됩니다.