玩转Spring Cache --- 开启基于注解的缓存功能@EnableCaching原理了解【享学Spring】(下)

简介: 玩转Spring Cache --- 开启基于注解的缓存功能@EnableCaching原理了解【享学Spring】(下)

ProxyCachingConfiguration


其实这个哥们的设计思想和ProxyTransactionManagementConfiguration如出一辙,只是各自处理各自的业务属性不同而已。


// @since 3.1  内部注入的Bean角色都是ROLE_INFRASTRUCTURE  建议先看下面的父类
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyCachingConfiguration extends AbstractCachingConfiguration {
  // 缓存注解的增强器:重点在CacheOperationSource和CacheInterceptor
  @Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor() {
    BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor();
    advisor.setCacheOperationSource(cacheOperationSource());
    advisor.setAdvice(cacheInterceptor());
    if (this.enableCaching != null) {
      advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
    }
    return advisor;
  }
  // 关于CacheOperationSource和CacheInterceptor是理解注解原理重要的两个类,放在下一章节讲解更妥
  // 注意CacheOperationSource是给CacheInterceptor用的
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public CacheOperationSource cacheOperationSource() {
    return new AnnotationCacheOperationSource();
  }
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public CacheInterceptor cacheInterceptor() {
    CacheInterceptor interceptor = new CacheInterceptor();
    interceptor.configure(this.errorHandler, this.keyGenerator, this.cacheResolver, this.cacheManager);
    interceptor.setCacheOperationSource(cacheOperationSource());
    return interceptor;
  }
}
// 抽象父类:定义和管理了Caching相关的API、类们
@Configuration
public abstract class AbstractCachingConfiguration implements ImportAware {
  // 这些属性都是protected的,子类可以直接访问哦~~~
  @Nullable
  protected AnnotationAttributes enableCaching;
  @Nullable
  protected Supplier<CacheManager> cacheManager;
  @Nullable
  protected Supplier<CacheResolver> cacheResolver; // 缓存注解的处理器
  @Nullable
  protected Supplier<KeyGenerator> keyGenerator; // key的生成器
  @Nullable
  protected Supplier<CacheErrorHandler> errorHandler; // 错误处理器
  // 继承此抽象类前提条件:必须标注@EnableCaching注解~
  @Override
  public void setImportMetadata(AnnotationMetadata importMetadata) {
    this.enableCaching = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false));
    if (this.enableCaching == null) {
      throw new IllegalArgumentException("@EnableCaching is not present on importing class " + importMetadata.getClassName());
    }
  }
  // 可以通过实现CachingConfigurer接口来**指定缓存使用的默认**的:
  // 缓存管理器
  // 缓存解析器
  // key生成器
  // 错误处理器
  @Autowired(required = false)
  void setConfigurers(Collection<CachingConfigurer> configurers) {
    if (CollectionUtils.isEmpty(configurers)) {
      return;
    }
    // CachingConfigurer的实现类,最多只能有一个
    if (configurers.size() > 1) {
      throw new IllegalStateException(configurers.size() + " implementations of " +
          "CachingConfigurer were found when only 1 was expected. " +
          "Refactor the configuration such that CachingConfigurer is " +
          "implemented only once or not at all.");
    }
    CachingConfigurer configurer = configurers.iterator().next();
    useCachingConfigurer(configurer);
  }
  /**
   * Extract the configuration from the nominated {@link CachingConfigurer}.
   */
  protected void useCachingConfigurer(CachingConfigurer config) {
    this.cacheManager = config::cacheManager;
    this.cacheResolver = config::cacheResolver;
    this.keyGenerator = config::keyGenerator;
    this.errorHandler = config::errorHandler;
  }
}


可以看到@EnableCaching这个注解的模式和@EnableTransactionManagement的效果是何其相似,所以掌握模式往往比掌握具体某一种技术更重要~


上面配置类向容器放入的三个Bean:BeanFactoryCacheOperationSourceAdvisor、CacheOperationSource、CacheInterceptor它是AOP处理缓存注解的核心,这在下一章节有详细的解释说明~


总结


本文先介绍了@EnableCaching它开启缓存注解支持的基本原理,从本文更应该得到的一个道理是:掌握模式往往比掌握具体的一门技术更加重要,这也就是战略和战术的区别吧~

相关文章
|
21天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
44 1
|
21天前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
42 0
|
11天前
|
Java 容器
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
12 0
|
21天前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
26 1
|
22天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0
|
30天前
|
存储 JavaScript 前端开发
Spring Boot + Vue: 实现文件导入导出功能
本文介绍了使用Spring Boot和Vue实现文件导入导出的步骤。在后端,Spring Boot通过`MultipartFile`接收上传文件,保存至服务器,并使用`ResponseEntity`提供文件下载。前端部分,Vue项目借助`axios`发送HTTP请求,实现文件选择、上传及下载功能。这种前后端分离的实现方式提高了应用的可维护性和可扩展性。
23 2
|
1月前
|
缓存 NoSQL Java
spring cache整合redis实现springboot项目中的缓存功能
spring cache整合redis实现springboot项目中的缓存功能
45 1
|
22天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
38 0
|
2月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
48 0
|
30天前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
106 0