如何从SpringBoot的应用程序上下文中获取CaffeineCacheManager?

我想使用自定义WrappingCacheManager作为caffeineCacheManager的装饰器。

当前配置是使用caffeine.newBuilder()...强制创建的,我想使用以下属性将其替换为声明性版本:

spring.cache.caffeine.spec=maximumSize=500,expireAfterWrite=60s

不幸的是,在应用程序上下文中没有caffeineCacheManager类型的bean,因此无法自然注入和包装。

意图:

// now it fails with NoSuchBeanDefinitionException

@Configuration
class CacheConfig1 {

  @Bean
  CacheManager cacheManager(caffeineCacheManager caffeineCacheManager) {
    return new WrappingCacheManager(caffeineCacheManager);
  }
}

当前使用的变体:

@Configuration
class CacheConfig2 {

  @Bean
  CacheManager cacheManager() {

    var cfg = caffeine.newBuilder().expireAfterWrite(60,TimeUnit.SECONDS).maximumSize(500);

    caffeineCacheManager caffeineCacheManager = new caffeineCacheManager();
    caffeineCacheManager.setcaffeine(cfg);

    return new WrappingCacheManager(caffeineCacheManager);
  }
}

pom.xml

中的依赖项片段
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.7.RELEASE</version>
</parent>

...

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>com.github.ben-manes.caffeine</groupId>
  <artifactId>caffeine</artifactId>
</dependency>

如何将caffeineCacheManager注入到bean创建方法中,并能够围绕它创建包装器CacheManager

iCMS 回答:如何从SpringBoot的应用程序上下文中获取CaffeineCacheManager?

我没有找到注入Caffeine.from的方法,但是至少可以使用@Value函数从字符串创建Caffeine配置。因此,通过@Bean public CacheManager cacheManager( @Value("${spring.cache.caffeine.spec}") String caffeineSpec ) { var cfg = Caffeine.from(caffeineSpec); CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); caffeineCacheManager.setCaffeine(cfg); return new WrappingCacheManager(caffeineCacheManager); } 注入属性是令人满意的解决方案。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethodPerformance {
}

@Aspect
@Component
public class MyMethodPerformanceAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyMethodPerformanceAspect.class);

    public MyMethodPerformanceAspect() {
    }

    @Around("@annotation(MyMethodPerformance)")
    public Object logMethodPerfomance(ProceedingJoinPoint joinPoint) throws Throwable {
        Object var6;
        try {
            Long methodStartTime = System.currentTimeMillis();
            Object proceed = joinPoint.proceed();
            Long methodEndTime = System.currentTimeMillis();
            MethodSignature signature = (MethodSignature)joinPoint.getSignature();
            MDC.put("methodName",signature.getMethod().getName());
            MDC.put("className",signature.getMethod().getDeclaringClass().getName());
            MDC.put("duration",Long.toString(methodEndTime - methodStartTime));
            LOGGER.info("Method performance");
            var6 = proceed;
        } finally {
            MDC.clear();
        }

        return var6;
    }
}
本文链接:https://www.f2er.com/1925510.html

大家都在问