spring Sping Boot 中的Caffeine缓存

3lxsmp7m  于 2023-11-16  发布在  Spring
关注(0)|答案(3)|浏览(119)

我有这样的配置类:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    @Primary
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("dogsInHouse");
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .initialCapacity(200)
                .expireAfterAccess(Duration.ofDays(30))
                .maximumSize(500));
        return cacheManager;
    }
}

字符串
在属性文件中:

spring.jpa.show-sql=true


在服务中:

@Service
@Transactional(readOnly = true)
@Slf4j
@CacheConfig(cacheNames = {"dogsInHouse"})
public class DogsInHouseService {

    @Cacheable("dogsInHouse")
    public DogsInHouse findDogHouseEnFromDB (String key) {
        return dogsEnRepository.findByNameAndLangIs(key);
    }
}


但我总是在控制台中看到一个选择查询。但我看不到该高速缓存日志。

daolsyd0

daolsyd01#

application.properties中使用logging.level.org.springframework.cache=TRACE查看是否从该高速缓存中选取了该值。

**注意:**当您第一次点击服务时,它将从数据库中获取数据并将数据放入该高速缓存中,下次它将从该高速缓存中获取数据。

请在Sping Boot 应用程序中删除不需要的@CacheConfig
我使用spring-data-jpaMySQL进行了演示。
使用相同的配置。仅添加以供参考。

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    @Primary
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("dogsInHouse");
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .initialCapacity(200)
                .expireAfterAccess(Duration.ofDays(30))
                .maximumSize(500));
        return cacheManager;
    }
}

字符串

DogInHouse用于测试:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DogInHouse {

    @Id
    @GeneratedValue
    private int id;

    @Column(name = "name")
    private String name;

}

DogInHouseRepository用于测试:

public interface DogInHouseRepository extends JpaRepository<DogInHouse, Integer> {
}


我的测试服务类:

@Service
@Slf4j
public class DogsInHouseService {

    @Autowired
    private DogInHouseRepository dogsEnRepository;

    @Cacheable(value = "dogsInHouse")
    public Optional<DogInHouse> findDogHouseById(int key) {
        return dogsEnRepository.findById(key);
    }

}

application.properties用于测试:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=Anish@123
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.springframework.cache=TRACE


我的pom.xml有这些依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <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>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
</dependencies>

我的申请日志:
首次服务点击:

2023-10-21T22:22:16.575+05:30 TRACE 14989 --- [nio-8080-exec-3] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '1' for operation Builder[public java.util.Optional com.example.springbootmysql.DogsInHouseService.findDogHouseById(int)] caches=[dogsInHouse] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
2023-10-21T22:22:16.576+05:30 TRACE 14989 --- [nio-8080-exec-3] o.s.cache.interceptor.CacheInterceptor   : No cache entry for key '1' in cache(s) [dogsInHouse]
2023-10-21T22:22:16.577+05:30 TRACE 14989 --- [nio-8080-exec-3] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '1' for operation Builder[public java.util.Optional com.example.springbootmysql.DogsInHouseService.findDogHouseById(int)] caches=[dogsInHouse] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
2023-10-21T22:22:16.587+05:30 DEBUG 14989 --- [nio-8080-exec-3] org.hibernate.SQL                        : 
    select
        d1_0.id,
        d1_0.name 
    from
        dog_in_house d1_0 
    where
        d1_0.id=?


当前在该高速缓存中没有带有传递的键的值,因此,将通过Hibernate执行选择查询以从DB中获取值,并通过该键将值放入该高速缓存中。

第二次服务命中:

2023-10-21T22:23:33.485+05:30 TRACE 14989 --- [nio-8080-exec-6] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '1' for operation Builder[public java.util.Optional com.example.springbootmysql.DogsInHouseService.findDogHouseById(int)] caches=[dogsInHouse] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
2023-10-21T22:23:33.490+05:30 TRACE 14989 --- [nio-8080-exec-6] o.s.cache.interceptor.CacheInterceptor   : Cache entry for key '1' found in cache 'dogsInHouse'


这一次,该值存在于该高速缓存中,其键与之前传递的键相同,并且从该高速缓存中获取该值。

** Postman 输出:**


的数据

kpbpu008

kpbpu0082#

如果每次调用findDogHouseEnFromDB()方法时都在控制台中看到选择查询,这应该意味着缓存可能没有按预期工作。
在从Lokesh Gupta中阅读“Caffeine Cache with Spring Boot“之后,出于调试目的,您可以添加一个端点或方法来检查该高速缓存的内容,以确保条目按预期被缓存和驱逐。

@GetMapping(value = "/inspectCache")
public void inspectCache() {
    CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache("dogsInHouse");
    Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
    for (Map.Entry<Object, Object> entry : nativeCache.asMap().entrySet()) {
        System.out.println("Key = " + entry.getKey());
        System.out.println("Value = " + entry.getValue());
    }
}

字符串
注意事项:您可以将部分或全部配置移到application.properties文件中,而不是在Java配置文件中配置缓存属性。这可以简化配置并使其更易于管理。请参阅JVM语言的配置库

spring.cache.cache-names=dogsInHouse
spring.cache.caffeine.spec=initialCapacity=200,maximumSize=500,expireAfterAccess=720h


如果需要自定义缓存键生成,您可以考虑实现custom KeyGenerator或使用@Cacheable注解上的key属性来指定如何生成该高速缓存键。

@Cacheable(value = "dogsInHouse", key = "#key")
public DogsInHouse findDogHouseEnFromDB (String key) {
    return dogsEnRepository.findByNameAndLangIs(..);
}

ktecyv1j

ktecyv1j3#

根据您的配置,缓存应该可以工作。如果缓存失败,则是由于提供的代码以外的原因。
使用您的代码创建了一个工作演示:caffeine_cache

相关问题