An overview of the

In today’s highly concurrent Internet applications, cache plays an important role in improving program performance. Spring also introduced Cache support with 3.x, which is certainly a feature that Spring Boot supports today. Of course Spring Boot default SimpleCacheConfiguration, which USES ConcurrentMapCacheManager to implement caching. But this article will show you how to apply the Guava Cache to your Spring Boot application.

Guava Cache is a full memory local Cache implementation and provides thread-safe mechanisms, so it is particularly suitable for code where certain values are expected to be called multiple times

Let’s use Guava Cache as a local Cache to see how it works.

Welcome to My Personal Blog CodeSheep


The preparatory work

  • Prepare database and data table and insert corresponding experiment data (MySQL)

For example, I have prepared a user table with several records:

We will simulate database access to see the effects of the Guava Cache.


Springboot + MyBatis + MySQL + Guava Cache

Add the following dependencies to pom.xml:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <! --for mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <! --for Mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <! -- Spring boot Cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <! --for guava cache-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>27.0.1 - jre</version>
        </dependency>

    </dependencies>
Copy the code

Create the Guava Cache configuration class

Import the GuavaCache configuration file GuavaCacheConfig

@Configuration
@EnableCaching
public class GuavaCacheConfig {

    @Bean
    public CacheManager cacheManager() {
        GuavaCacheManager cacheManager = new GuavaCacheManager();
        cacheManager.setCacheBuilder(
                CacheBuilder.newBuilder().
                        expireAfterWrite(10, TimeUnit.SECONDS).
                        maximumSize(1000));
        returncacheManager; }}Copy the code

Guava Cache configuration is very simple, for example, the above code sets the Cache lifetime to 10 seconds and the maximum number of caches to 1000


Configure the application. The properties

server.port=82

Mysql data source configurationSpring. The datasource. Url = JDBC: mysql: / / 121.116.23.145:3306 / demo? useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# mybatis configuration
mybatis.type-aliases-package=cn.codesheep.springbt_guava_cache.entity
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true
Copy the code

Write business code for database operations and Guava Cache

  • Write the entity
public class User {

    private Long userId;
    private String userName;
    private Integer userAge;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) { this.userAge = userAge; }}Copy the code
  • Write the mapper
public interface UserMapper {

    List<User> getUsers();
    int addUser(User user);
    List<User> getUsersByName( String userName );
}
Copy the code
  • Write the service
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public List<User> getUsers() {
        return userMapper.getUsers();
    }

    public int addUser( User user ) {
        return userMapper.addUser(user);
    }

    @Cacheable(value = "user", key = "#userName")
    public List<User> getUsersByName( String userName ) {
        List<User> users = userMapper.getUsersByName( userName );
        System.out.println( "Read from database, not cache!" );
        returnusers; }}Copy the code

As you can see, we’ve annotated the getUsersByName interface with @cacheable. CachePut: @cacheevit: @cacheput: @cacheevit: @cacheevit: @cacheput: @cacheevit

  1. @Cacheable: configuration ingetUsersByNameMethod to indicate that its return value will be added to the cache. At the same time, during the query, the database will be obtained from the cache first. If the database does not exist, the access to the database will be initiated
  2. @CachePutWhen configured on a method, it can be cached according to parameters defining conditions@CacheableThe difference is the use@CachePutThe annotated method does not check the existence of the previously executed result in the cache before execution. Instead, the method is executed each time and the execution result is stored in the specified cache in the form of key-value pairs, so it is mainly used for data addition and modification operations
  3. @CacheEvict: Removes data from the cache when configured on a method.
  • Writing the controller
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    CacheManager cacheManager;

    @RequestMapping( value = "/getusersbyname", method = RequestMethod.POST)
    public List<User> geUsersByName( @RequestBody User user ) {
        System.out.println( "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --" );
        System.out.println("call /getusersbyname");
        System.out.println(cacheManager.toString());
        List<User> users = userService.getUsersByName( user.getUserName() );
        returnusers; }}Copy the code

Modify the Spring Boot application main class

Caching is explicitly enabled primarily on the startup class via the @enablecaching annotation

@SpringBootApplication
@MapperScan("cn.codesheep.springbt_guava_cache") @EnableCaching public class SpringbtGuavaCacheApplication { public static void main(String[] args) { SpringApplication.run(SpringbtGuavaCacheApplication.class, args); }}Copy the code

The final structure of the project is as follows:


The actual experiment

To the interface through multiple localhost: 82 / getusersbyname POST data to observe effect:

In the Guava Cache configuration file, the user is cached for 10 seconds.

How, the effect of cache is still very obvious!


Remember after

Due to the limited ability, if there is a mistake or improper place, please also criticize and correct, study together!

  • My Personal Blog: CodeSheep program sheep
  • Feng 2018 Year-end Gen of programmed Sheep


To subscribe to CodeSheep’s public account, long press or scan below, you can get more practical, understandable and reproducible original articles