Spring Boot Caffeine Caffeine

Integration of Caffeine and Spring Boot

Caffeine is a rewritten version of the Guava cache using Java 8 and will replace Guava in Spring Boot 2.0. If Caffeine occurs, Caffeine Cache Manager will be automatically configured. Using the spring.cache.cache-names attribute, you can create a cache at startup and customize it (in sequence) by configuring it as follows:

  • spring.cache.caffeine.spec: Special cache defined
  • com.github.benmanes.caffeine.cache.CaffeineSpec: bean definition
  • com.github.benmanes.caffeine.cache.Caffeine: bean definition

For example, the following configuration creates a foo and bar cache with a maximum number of 500 and a survival time of 10 minutes:

spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

In addition, if com.github.benmanes.caffeine.cache.CacheLoader is defined, it will automatically be associated with Caffeine Cache Manager. Since the CacheLoader associates all caches managed by the cache manager, it must be defined as CacheLoader < Object, Object>, and automatic configuration ignores all generic types.

Introducing 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>
	<version>2.6.0</version>
</dependency>

Support for opening caches

Use @ EnableCaching annotation to enable Spring Boot to support caching

@SpringBootApplication
@EnableCaching// Open the cache and specify what needs to be displayed
public class SpringBootStudentCacheCaffeineApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootStudentCacheCaffeineApplication.class, args);
	}
}

configuration file

Added special configuration for caching, such as maximum capacity, expiration time, etc.

spring.cache.cache-names=people
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s,refreshAfterWrite=5s

If refreshAfterWrite configuration is used, a CacheLoader must also be specified, such as:

/**
 * You must specify the Bean, refreshAfterWrite=5s for the configuration property to take effect.
 *
 * @return
 */
@Bean
public CacheLoader<Object, Object> cacheLoader() {

    CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() {

        @Override
        public Object load(Object key) throws Exception {
            return null;
        }

        // Rewriting this method returns the oldValue value back to refresh the cache
        @Override
        public Object reload(Object key, Object oldValue) throws Exception {
            return oldValue;
        }
    };

    return cacheLoader;
}

Caffeine configuration instructions:

  • Initial Capacity= [integer]: Initial cache space size
  • Maximum Size=[long]: Maximum number of caches
  • Maximum Weight=[long]: Maximum Weight of Cache
  • expireAfterAccess=[duration]: expires after a fixed time after the last write or access
  • expireAfterWrite=[duration]: After the last write, it expires for a fixed time
  • refreshAfterWrite=[duration]: refresh the cache at a fixed interval after creating or last updating the cache
  • weakKeys: Open a weak reference to key
  • Weak Values: Open weak references to value
  • softValues: Open the soft reference to value
  • recordStats: Developing Statistical Functions

Be careful:

  • When expireAfterWrite and expireAfterAccess colleagues exist, expireAfterWrite shall prevail.
  • Maximum Size and Maximum Weight cannot be used simultaneously
  • Weak Values and softValues cannot be used simultaneously

Sample code

/**
 * @author yuhao.wang
 */
@Service
public class PersonServiceImpl implements PersonService {
    private static final Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);

    @Autowired
    PersonRepository personRepository;

    @Override
    @CachePut(value = "people", key = "#person.id")
    public Person save(Person person) {
        Person p = personRepository.save(person);
        logger.info("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }

    @Override
    @CacheEvict(value = "people")//2
    public void remove(Long id) {
        logger.info("Deleted id,key by" + id + "Data caching");
        //No actual deletion is done here.
    }

    /**
     * Cacheable
     * value: Cache the prefix of key.
     * key: Cache the suffix of key.
     * sync: Set if the cache expires and only one request is placed to request the database, other requests are blocked, the default is false.
     */
    @Override
    @Cacheable(value = "people", key = "#person.id", sync = true)
    public Person findOne(Person person, String a, String[] b, List<Long> c) {
        Person p = personRepository.findOne(person.getId());
        logger.info("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }

    @Override
    @Cacheable(value = "people1")//3
    public Person findOne1() {
        Person p = personRepository.findOne(2L);
        logger.info("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }

    @Override
    @Cacheable(value = "people2")//3
    public Person findOne2(Person person) {
        Person p = personRepository.findOne(person.getId());
        logger.info("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }
}

Reference resources:

Source code: https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

spring-boot-student-cache-caffeine project

Laying-cache, a multi-level caching framework for monitoring This is an implementation of my open source multi-level caching framework. If you are interested, take a look at it.

Keywords: Programming Spring github Java Attribute

Added by ColinP on Mon, 23 Sep 2019 06:48:07 +0300