spring-boot-auto-configure:spring.cache.type如何生效

转载请标明出处:
https://blog.csdn.net/bingospunky/article/details/79700773
本文出自马彬彬的博客

spring.cache.type: redis如何生效的?

在使用spring cache时,spring已经默认支持了几种缓存实现方式,我们可以通过在spring-boot配置文件中添加spring.cache.type: redis来设置使用redis方式实现cache。那么这句配置是如何剩下的呢?

在spring-boot-autoconfigure的jar文件中,org.springframework.boot.autoconfigure.cache包下有一系列XXXCacheConfiguration,在这些XXXCacheConfiguration中,有很多@ConditionalXXX注解,这样会进行一定的过滤,但仅靠@ConditionalXXX注解是不够的,因为@ConditionalXXX注解生效后,还不能辨别出唯一的一个XXXCacheConfiguration
每个XXXCacheConfiguration还有这样一个注解@Conditional({CacheCondition.class})。

@Conditional的声明是这样的:

Code1
org.springframework.context.annotation.Conditional

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

Condition的声明式这样的:

Code2
org.springframework.context.annotation

public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

Code3
org.springframework.boot.autoconfigure.cache.CacheCondition

class CacheCondition extends SpringBootCondition {
    CacheCondition() {
    }
    public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String sourceClass = "";
        if (metadata instanceof ClassMetadata) {
            sourceClass = ((ClassMetadata)metadata).getClassName();
        }
        Builder message = ConditionMessage.forCondition("Cache", new Object[]{sourceClass});
        RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), "spring.cache.");
        if (!resolver.containsProperty("type")) {
            return ConditionOutcome.match(message.because("automatic cache type"));
        } else {
            CacheType cacheType = CacheConfigurations.getType(((AnnotationMetadata)metadata).getClassName());
            String value = resolver.getProperty("type").replace('-', '_').toUpperCase();
            return value.equals(cacheType.name()) ? ConditionOutcome.match(message.because(value + " cache type")) : ConditionOutcome.noMatch(message.because(value + " cache type"));
        }
    }
}

CacheCondition继承SpringBootCondition。SpringBootCondition的代码如下:

Code4
org.springframework.boot.autoconfigure.condition.SpringBootCondition

public abstract class SpringBootCondition implements Condition {
    private final Log logger = LogFactory.getLog(this.getClass());
    public SpringBootCondition() {
    }
    public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String classOrMethodName = getClassOrMethodName(metadata);
        try {
            ConditionOutcome outcome = this.getMatchOutcome(context, metadata);
            this.logOutcome(classOrMethodName, outcome);
            this.recordEvaluation(context, classOrMethodName, outcome);
            return outcome.isMatch();
        } catch (NoClassDefFoundError var5) {
            throw new IllegalStateException("Could not evaluate condition on " + classOrMethodName + " due to " + var5.getMessage() + " not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)", var5);
        } catch (RuntimeException var6) {
            throw new IllegalStateException("Error processing condition on " + this.getName(metadata), var6);
        }
    }
}

被@Conditional({CacheCondition.class})标记的XXXCacheConfiguration,会根据CacheCondition的matches方法的返回值来判断该XXXCacheConfiguration是否生效。

当spring加载的时候,Code4第4行的方法会被不断的回调,其中第二个参数是标记@Conditional({CacheCondition.class})这个注解的类的Class。比如这次回调传进来的metadata是RedisCacheConfiguration的Class生成的。在Code3的getMatchOutcome方法中,第7行的sourceClass的值是“RedisCacheConfiguration”,第14行,会根据RedisCacheConfiguration获取到的枚举类型是:CacheType.REDIS,第15行获取的value的值就是我们在配置文件中设置的spring.cache.type: redis的大写形式REDIS。这样matches方法会返回true,该XXXCacheConfiguration生效。

XXXCacheConfiguration为JCacheCacheConfiguration时,字符串不匹配,该JCacheCacheConfiguration不生效。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值