SpringBoot2-Глава 5: Интеграция EhCache

задняя часть GitHub Spring Gson

В последней главе мы кратко представили использование Springboot Gson в качестве анализатора сообщений, В этой главе мы будем использовать аннотации, связанные с кешем, в springboot.

GitHub для этого проекта: https://github.com/pc859107393/Go2SpringBoot.git

Учащиеся, заинтересованные в общении со springboot для быстрой разработки, могут добавить следующую группу пингвинов.

行走的java全栈

Использование кэширующих аннотаций SpringBoot

В дополнительной части я уже представил аннотации springcache. Точно так же мы можем видеть, что SpringBoot предустановил некоторые общие кеши, проанализировав исходный код. Мы можем увидеть, что там есть:

  • org.springframework.cache
    • concurrent
      • ConcurrentMapCacheИспользовать ConcurrentMap в качестве технологии кэширования (по умолчанию)
    • support
      • AbstractCacheManagerАбстракция CacheManager
      • NoOpCacheПростой кеш, который на самом деле не хранит
      • SimpleCacheManagerПростой кеш, часто используемый для тестирования
    • ehcache
      • EhCacheCache
    • CaffeineCache
      • CaffeineCache
    • jcache
      • JCacheCache
    • transaction
      • AbstractTransactionSupportingCacheManagerАбстрактный менеджер кэша с поддержкой транзакций

Конечно, вышеуказанные классы по умолчанию интегрированы только Springboot.Чтобы использовать кеш, сначала нам нужно добавить соответствующие аннотации к входному классу SpringBoot, чтобы включить кеш.

@SpringBootApplication
@EnableWebMvc
@EnableSwagger2
@MapperScan(value = ["cn.acheng1314.base.dao"])
@Configuration
@EnableTransactionManagement
@EnableCaching  //使用这个注解开启缓存
class BaseApplication : WebMvcConfigurer {
    //···省略代码
}

Конечно, по умолчанию Spring будет использовать ConcurrentMapCacheManager, как использовать EhCache? Нам нужно внести изменения в файл конфигурации. Сначала добавьте зависимости Ehcache:compile 'net.sf.ehcache:ehcache:2.10.5', а затем согласовываем настройку Ehcache в конфигурационном файле, следующим образом:

#Ehcache配置
spring.cache.ehcache.config=classpath:/ehcache.xml
spring.cache.type=ehcache

Это конец написания и игры? Однако нет, нам нужно сначала реализовать конфигурацию ehcache, а затем реализовать аннотации на сервисном уровне, чтобы кеш заработал, следующим образом:

<!--这里是我们的ehcache配置-->
<ehcache
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">
    <!--缓存路径,用户目录下的base_ehcache目录-->
    <diskStore path="user.home/base_ehcache"/>  

    <defaultCache
            maxElementsInMemory="20000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>
    <!--缓存文件名:cache_user,同样的可以配置多个缓存-->
    <cache name="cache_user"
           maxElementsInMemory="20000"
           eternal="true"
           overflowToDisk="true"
           diskPersistent="false"
           timeToLiveSeconds="0"
           diskExpiryThreadIntervalSeconds="120"/>

</ehcache>

Далее давайте взглянем на применение аннотаций кэша на сервисном уровне. Использование каждой аннотации было представлено в моей дополнительной главе, и я не буду здесь подробно останавливаться на примерах:

import cn.acheng1314.base.dao.UserDao
import cn.acheng1314.base.domain.User
import com.baomidou.mybatisplus.plugins.pagination.Pagination
import com.baomidou.mybatisplus.service.impl.ServiceImpl
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.CacheConfig
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import kotlin.collections.ArrayList

@Service(value = "userService") 
//这里需要和配置文件的cache的name对应,否则产生异常某个名为XX的缓存找不到
@CacheConfig(cacheNames = ["cache_user"])  
class UserServiceImpl : ServiceImpl<UserDao, User>() {

    @Autowired
    lateinit var userDao: UserDao

    fun findUserByPage(pageNum: Int, pageSize: Int): ArrayList<User> {
        return try {
            val pagination = Pagination(pageNum, pageSize)
            setTotalPage(pagination.pages)
            userDao.findAllByPage(pagination)
        } catch (e: Exception) {
            arrayListOf()
        }
    }

    var totalPage: Long? = null
    fun setTotalPage(pages: Long) {
        this.totalPage = pages
    }

    @Cacheable(sync = true)
    fun findAll() = baseMapper.selectList(null)

}

Давайте запустим проект здесь, и мы увидим, что скорость первого доступа будет немного медленнее, чем последующие.Точно так же мы вручную добавляем значение в базу данных, а затем снова обращаемся к этому, мы обнаружим, что вручную добавленное значение не будет считано, поэтому можно будет доказать, что наш кеш был успешно установлен.

Конкретный эффект можно увидеть на скриншоте ниже:

图5-1 缓存成功后,左边数据库手动插入后,右边的缓存数据中并未出现手动插入数据

На приведенном выше рисунке мы ясно видим, что после того, как я вручную вставил фрагмент данных в рисунок, он не отображается на правильном рисунке, что указывает на то, что наш кеш успешно установлен.

Более подробный код см. в исходном коде моего проекта, спасибо за чтение.