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

相关文章
|
10月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1795 5
|
10月前
|
存储 缓存 Java
Spring中@Cacheable、@CacheEvict以及其他缓存相关注解的实用介绍
缓存是提升应用性能的重要技术,Spring框架提供了丰富的缓存注解,如`@Cacheable`、`@CacheEvict`等,帮助开发者简化缓存管理。本文介绍了如何在Spring中配置缓存管理器,使用缓存注解优化数据访问,并探讨了缓存的最佳实践,以提升系统响应速度与可扩展性。
451 0
Spring中@Cacheable、@CacheEvict以及其他缓存相关注解的实用介绍
|
缓存 Java 数据库
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
934 89
|
缓存 Java 数据库连接
怎么使用注解开启二级缓存,注解应该放在那里?
在 MyBatis 中,使用 `@CacheNamespace` 注解可开启二级缓存,该注解应添加在 Mapper 接口上。通过配置 `eviction`、`flushInterval`、`size` 等参数,可以控制缓存行为。此外,实体类需实现 `Serializable` 接口以确保缓存正常工作。
287 1
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
407 32
|
存储 缓存 NoSQL
Spring Cache缓存框架
Spring Cache是Spring体系下的标准化缓存框架,支持多种缓存(如Redis、EhCache、Caffeine),可独立或组合使用。其优势包括平滑迁移、注解与编程两种使用方式,以及高度解耦和灵活管理。通过动态代理实现缓存操作,适用于不同业务场景。
812 0
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
603 4
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot提供了简便的方式来集成和使用分布式缓存。通过Redis和Memcached等缓存方案,可以显著提升应用的性能和扩展性。合理配置和优化缓存策略,可以有效避免常见的缓存问题,保证系统的稳定性和高效运行。
535 3
|
缓存 NoSQL Java
Spring Cache 缓存原理与 Redis 实践
Spring Cache 缓存原理与 Redis 实践
807 0
|
缓存 NoSQL Java
spring cache整合redis实现springboot项目中的缓存功能
spring cache整合redis实现springboot项目中的缓存功能
1041 1