首页 > 其他分享 >spring - springmvc - @EnableCaching

spring - springmvc - @EnableCaching

时间:2024-03-07 20:56:40浏览次数:19  
标签:customer 缓存 addresses springmvc spring getAddress EnableCaching cacheManager pub

@EnableCaching
@EnableCaching注释在应用程序中启用注释驱动的缓存管理功能,并允许我们在应用程序中使用@Cacheable和@CacheEvict注释。
具有类似功能的 XML 等效项是cache:*命名空间:

@Configuration
@EnableCaching
public class CacheConfig {
 
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(
          Arrays.asList(new ConcurrentMapCache("default")));
        return cacheManager;
    }
}

该注释还有以下选项:
mode — 指示应如何应用缓存建议
order — 指示在特定连接点应用时执行缓存顾问的顺序
proxyTargetClass — 指示是否要创建基于子类 (CGLIB) 的代理,而不是基于标准 Java 接口的代理
此配置再次可以通过实现CachingConfigurerSupport类的@Configuration类进行自定义:

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Bean
    @Override
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(
          Arrays.asList(new ConcurrentMapCache("default")));
        return cacheManager;
    }

    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new MyKeyGenerator();
    }
}

当然,我们也可以通过 XML 配置启用缓存管理:

<beans>
    <cache:annotation-driven />

    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean 
                  class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" 
                  name="addresses"/>
            </set>
        </property>
    </bean>
</beans>

当然,我们也可以通过 XML 配置启用缓存管理:

@Component
public class SimpleCacheCustomizer 
  implements CacheManagerCustomizer<ConcurrentMapCacheManager> {

    @Override
    public void customize(ConcurrentMapCacheManager cacheManager) {
        cacheManager.setCacheNames(asList("users", "transactions"));
    }
}

CacheAutoConfiguration 自动配置会 选取这些定制器,并在完成初始化之前将它们应用到当前的CacheManager 。
为方法启用缓存行为的最简单方法是使用@Cacheable对其进行划分,并使用将存储结果的缓存名称对其进行参数化:
getAddress ()调用将在实际调用该方法之前首先检查缓存地址,然后缓存结果。
虽然在大多数情况下一个缓存就足够了,但 Spring 框架还支持将多个缓存作为参数传递:

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

@Cacheable({"addresses", "directory"})
public String getAddress(Customer customer) {...}

现在,将所有方法设置为@Cacheable会出现什么问题?
问题是尺寸。我们不想用不经常需要的值填充缓存。缓存可能会变得非常大、非常快,我们可能会保留大量陈旧或未使用的数据。
我们可以使用@CacheEvict注解来指示删除一个或多个/所有值,以便可以将新值再次加载到缓存中:

@CacheEvict(value="addresses", allEntries=true)
public String getAddress(Customer customer) {...}

这里我们使用附加参数allEntries结合要清空的缓存;这将清除缓存地址中的所有条目并为新数据做好准备。
虽然@CacheEvict通过删除陈旧和未使用的条目来减少在大型缓存中查找条目的开销,但我们希望避免从缓存中逐出太多数据。
相反,每当我们更改条目时,我们都会有选择地更新它们。
通过@CachePut注解,我们可以在不干扰方法执行的情况下更新缓存的内容。也就是说,该方法将始终被执行并缓存结果:

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

@Cacheable和@CachePut之间的区别在于,@Cacheable将跳过运行该方法,而@CachePut将实际运行该方法,然后将其结果放入缓存中。

如果我们想使用多个相同类型的注解来缓存一个方法怎么办?我们来看一个错误的例子:

@CacheEvict("addresses")
@CacheEvict(value="directory", key=customer.name)
public String getAddress(Customer customer) {...}

上面的代码将无法编译,因为 Java 不允许为给定方法声明相同类型的多个注释。
上述问题的解决方法是:`

@Caching(evict = { 
  @CacheEvict("addresses"), 
  @CacheEvict(value="directory", key="#customer.name") })
public String getAddress(Customer customer) {...}

如上面的代码片段所示,我们可以使用@Caching将多个缓存注解分组,并使用它来实现我们自己定制的缓存逻辑。
使用@CacheConfig注释,我们可以将一些缓存配置简化到类级别的单个位置,这样我们就不必多次声明:

@CacheConfig(cacheNames={"addresses"})
public class CustomerDataService {

    @Cacheable
    public String getAddress(Customer customer) {...}
}

有时,缓存可能并不适用于所有情况下的方法。
重用@CachePut注释中的示例,这将每次执行该方法并缓存结果:

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

果我们想要更多地控制注释何时处于活动状态,我们可以使用条件参数参数化@CachePut,该条件参数采用 SpEL 表达式,并确保根据评估该表达式来缓存结果:

@CachePut(value="addresses", condition="#customer.name=='Tom'")
public String getAddress(Customer customer) {...}

我们还可以根据方法的输出而不是通过except参数的输入来控制缓存:

@CachePut(value="addresses", unless="#result.length()<64")
public String getAddress(Customer customer) {...}`

上述注释将缓存地址,除非它们短于 64 个字符。
重要的是要知道条件和除非参数可以与所有缓存注释结合使用。
这种条件缓存对于管理大型结果非常有效。它对于根据输入参数自定义行为也很有用,而不是对所有操作强制执行通用行为。
基于 XML 的声明式缓存
如果我们无法访问应用程序的源代码,或者想要从外部注入缓存行为,我们还可以使用基于 XML 的声明性缓存。
这是我们的 XML 配置:

<!-- the service that you wish to make cacheable -->
<bean id="customerDataService" 
  class="com.your.app.namespace.service.CustomerDataService"/>

<bean id="cacheManager" 
  class="org.springframework.cache.support.SimpleCacheManager"> 
    <property name="caches"> 
        <set> 
            <bean 
              class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" 
              name="directory"/> 
            <bean 
              class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" 
              name="addresses"/> 
        </set> 
    </property> 
</bean>
<!-- define caching behavior -->
<cache:advice id="cachingBehavior" cache-manager="cacheManager">
    <cache:caching cache="addresses">
        <cache:cacheable method="getAddress" key="#customer.name"/>
    </cache:caching>
</cache:advice>

<!-- apply the behavior to all the implementations of CustomerDataService interface->
<aop:config>
    <aop:advisor advice-ref="cachingBehavior"
      pointcut="execution(* com.your.app.namespace.service.CustomerDataService.*(..))"/>
</aop:config>

这是等效的 Java 配置

@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(
          new ConcurrentMapCache("directory"), 
          new ConcurrentMapCache("addresses")));
        return cacheManager;
    }
}

这是我们的CustomerDataService:

@Component
public class CustomerDataService {
 
    @Cacheable(value = "addresses", key = "#customer.name")
    public String getAddress(Customer customer) {
        return customer.getAddress();
    }
}

标签:customer,缓存,addresses,springmvc,spring,getAddress,EnableCaching,cacheManager,pub
From: https://www.cnblogs.com/dkpp/p/18059730

相关文章

  • SpringBoot 支付宝付款接口类、支付异步回调函数模板
    1.付款接口类1.1.引入Maven依赖<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.38.221.ALL</version></dependency>1.2.将下面代码保存为AlipayTemplate.java@Config......
  • SpringBoot-重要注解(1)
    ConfigurationProperties注解https://blog.csdn.net/skh2015java/article/details/120141409@Import、@ImportAutoConfigurationhttps://www.cnblogs.com/imyjy/p/16092825.html当我们需要在一个配置类中导入另一个Configuration配置类时,可以使用@Import、@ImportAuto......
  • Spring框架Bean对象的五个作用域
    ​ 一、前言:Bean对象简介在Spring项目中,那些由Spring IoC容器所管理的对象,称为bean。简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。 而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。上一段描述......
  • spring - mvc
    springmvc1.@Autowired@ComponentpublicclassFooService{@AutowiredprivateFooFormatterfooFormatter;}2.通过@Qualifier自动装配例如,让我们看看如何使用@Qualifier注释来指示所需的bean。首先,我们将定义2个Formatter类型的bean:@Component("fooFo......
  • SpringBoot3+Consul配置,启动后,居然不读bootstrap.yml的配置文件,直接连本地localhost:8
    问题描述如题。bootstrap.yml的配置文件: consul控制台打印的日志: 解决方案:booststrap.yml的配置文件缩进搞错了,所以压根就没有读到配置。正确的缩进:  ......
  • spring-webClient-响应式http客户端
    1.WebClient简介WebClient是SpringWebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。WebFlux对标SpringMvc,WebClient相当于RestTemplate,同时也是Spring官方的Http请求工具。2.传统阻塞IO模型VS响应式IO模型传统阻塞IO模型RestTem......
  • spring-restTemplate-网络请求
    1,引言  现如今的IT项目,由服务端向外发起网络请求的场景,基本上处处可见!传统情况下,在服务端代码里访问http服务时,一般会使用JDK的HttpURLConnection或者Apache的HttpClient,不过这种方法使用起来太过繁琐,而且api使用起来非常的复杂,还得操心资源回收。  RestTempl......
  • Spring-@Bean-注解
    1.作用用于将对象存入spring的ioc容器中。@controller、@Service、@Component、@Configuration、@Repository等几个注解是一样的,都是负责将对象存入容器当中,而@Bean是用在方法上,将当前方法的返回值对象放到容器当中。2.使用@Bean一般出现在方法上面,也可用于自定义......
  • 若依集成CIM(即时推送系统)实现将服务端修改为SpringBoot+Vue前后端分离版(文末见代码
    ​ 场景若依前后端分离版本地搭建开发环境并运行项目的教程:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662 CIMGitee地址:https://gitee.com/farsunset/cimCIM项目是基于mina或者netty框架下的推送系统,我们平常使用第三方的推送SDK,如极光推送,百度......
  • Spring-@ControllerAdvice-全局处理注解
    1,@ControllerAdvice介绍@ControllerAdvice是Spring框架提供的一个注解,用于定义全局的异常处理器和全局数据绑定。它通常用于集中处理应用程序中的异常,并提供统一的异常处理逻辑。2,@ControllerAdvice的基本使用packageorg.springframework.web.bind.annotation;importj......