玩转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它开启缓存注解支持的基本原理,从本文更应该得到的一个道理是:掌握模式往往比掌握具体的一门技术更加重要,这也就是战略和战术的区别吧~

相关文章
|
5天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
21 0
|
12天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
36 4
SpringBoot必须掌握的常用注解!
|
14天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
54 2
|
14天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
30 1
|
9天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
8 0
|
21天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
161 2
|
7天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
18 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
3天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
11 2