tbbc / cache-bundle
Symfony 扩展包 - 缓存抽象和方法注解用于控制缓存
Requires
- doctrine/cache: >=1.0
- jms/aop-bundle: >=1.0.0,<1.2-dev
- jms/metadata: 1.*
- symfony/expression-language: ~2.4
- symfony/framework-bundle: >=2.0
Requires (Dev)
- phpunit/phpunit: 3.*
- symfony/browser-kit: ~2.3
- symfony/class-loader: ~2.3
- symfony/finder: ~2.3
- symfony/yaml: ~2.3
Suggests
- doctrine/cache: Allows to use Doctrine Cache library
This package is not auto-updated.
Last update: 2024-09-14 16:24:03 UTC
README
添加 缓存抽象 和 方法注解 以控制缓存。Cache 组件的当前实现是 Doctrine\Common\Cache 的包装器(代理)。
状态
概览
TbbcCacheBundle 集成 Symfony 与非侵入式应用缓存管理系统。它通过使用 AOP 机制和 PHP 语言表达式,为开发者提供基于注解的缓存控制。
<?php namespace My\Manager; use My\Model\Product; use Tbbc\CacheBundle\Annotation\Cacheable; use Tbbc\CacheBundle\Annotation\CacheUpdate; use Tbbc\CacheBundle\Annotation\CacheEvict; class ProductManager { /** * @Cacheable(caches="products", key="sku") */ public function getProduct($sku, $type = 'book') { // fetch a product from a repository or whatever $product = $this->productRepository->getByType($sku, 'book'); return $product; } /** * @CacheUpdate(caches="products", key="product.getSku()") */ public function updateProduct(Product $product) { $product = $this->productRepository->save($product); return $product; } /** * @CacheEvict(caches="products", key="product.getSku()") */ public function removeProduct(Product $product) { $product = $this->productRepository->remove($product); } }
特性
- 支持
@Cacheable
、@CacheUpdate
、@CacheEvict
注解 - TTL 策略,允许您自定义缓存保留时间
- 命名空间缓存管理器
- 多个缓存管理器
- Doctrine/ArrayCache
- Doctrine/ApcCache
- Doctrine/MemcachedCache
- Doctrine/RedisCache
- Symfony Debug Toolbar 集成
文档
安装
首先,使用 composer 安装扩展包
$ php composer.phar require tbbc/cache-bundle
接下来,在 app/AppKernel.php
中激活扩展包
<?php // ... public function registerBundles() { $bundles = array( //... new Tbbc\CacheBundle\TbbcCacheBundle(), ); // ... }
配置
services: my_manager.product: class: My\Manager\ProductManager tags: - { name: tbbc_cache.cache_eligible } tbbc_cache: annotations: { enabled: true } manager: simple_cache key_generator: simple_hash metadata: use_cache: true # Whether or not use metadata cache cache_dir: %kernel.cache_dir%/tbbc_cache cache: products: type: memcached servers: memcached-01: { host: localhost, port: 11211 }
注意:如果您想使用注解来使用此服务,则必须在服务定义中强制使用 tbbc_cache.cache_eligible
标签。
使用
基于注解的缓存(推荐)
推荐
如果有人希望避免每次添加一些缓存逻辑时都重复代码,则扩展包可以通过使用 AOP 方法及注解来自动化此过程。
扩展包提供了以下注解
@Cacheable 注解
@Cacheable 注解用于将方法的结果自动存储到缓存中。
当调用标记了 @Cacheable 注解的方法时,扩展包会检查缓存中是否存在条目。如果找到,则返回缓存结果而无需实际执行方法。
如果没有找到缓存条目,则执行方法,并自动将结果存储到缓存中。
<?php namespace My\Manager; use My\Model\Product; use Tbbc\CacheBundle\Annotation\Cacheable; class ProductManager { /** * @Cacheable(caches="products", key="sku") */ public function getProduct($sku, $type = 'book') { // fetch a product from a repository or whatever $product = $this->productRepository->getByType($sku, 'book'); return $product; } }
@CacheEvict 注解
@CacheEvict 注解允许方法触发缓存填充或删除。
当方法被标记为 @CacheEvict 注解时,扩展包将执行该方法,然后自动尝试删除带有提供键的缓存条目。
<?php namespace My\Manager; use My\Model\Product; use Tbbc\CacheBundle\Annotation\CacheEvict; class ProductManager { /** * @CacheEvict(caches="products", key="product.getSku()") */ public function removeProduct(Product $product) { // saving product ... } }
也可以通过将 allEntries
参数设置为 true
来完全清除缓存。
⚠️ 重要提示:使用 allEntries
选项时要非常小心,如果您为不同命名空间使用相同的缓存管理器,则整个缓存管理器将被清除。这是当前底层 Doctrine Cache 库的限制。
<?php namespace My\Manager; use My\Model\Product; use Tbbc\CacheBundle\Annotation\CacheEvict; class ProductManager { /** * @CacheEvict(caches="products", allEntries=true) */ public function removeProduct(Product $product) { // saving product ... } }
注意:如果您还提供了 key
,它将被忽略,缓存将被清除。
@CacheUpdate 注解
@CacheUpdate 注解对于需要更新缓存而不干扰方法执行的情况非常有用。
当一个方法被@CacheUpdate注解标记时,组件将始终执行该方法,然后将自动尝试使用方法结果更新缓存条目。
<?php namespace My\Manager; use My\Model\Product; use Tbbc\CacheBundle\Annotation\CacheUpdate; class ProductManager { /** * @CacheUpdate(caches="products", key="product.getSku()") */ public function updateProduct(Product $product) { // saving product.... return $product; } }
表达式语言
对于键生成,可以使用Symfony表达式语言。
/** * @CacheUpdate(caches="products", key="product.getSku()") */ public function updateProduct(Product $product) { // do something }
表达式语言允许您检索传递给方法的所有参数,并使用它来生成缓存键。
标准缓存使用(无注解)
必须将CacheManager
实例注入到需要缓存管理的服务中。
CacheManager
提供对每个配置的缓存的访问(请参阅配置部分)。每个缓存实现CacheInterface。
使用
<?php namespace My\Manager; use Tbbc\CacheBundle\Annotation\Cacheable; class ProductManager { private $cacheManager; private $keyGenerator; public function __construct(CacheManagerInterface $cacheManager, KeyGeneratorInterface $keyGenerator) { $this->cacheManager = $cacheManager; $this->keyGenerator = $keyGenerator; } public function getProduct($sku, $type = 'book') { $cacheKey = $this->keyGenerator->generateKey($sku); $cache = $this->cacheManager->getCache('products'); if ($product = $cache->get($cacheKey)) { return $product; } $product = $this->productRepository->findProductBySkuAndType($sku, $type); $cache->set($cacheKey, $product); return $product; } public function saveProduct(Product $product) { $this->productRepository->save($product); $cacheKey = $this->keyGenerator->generateKey($product->getSku()); $cache = $this->cacheManager->getCache('products'); $cache->delete($cacheKey); } }
自定义缓存管理器
默认情况下,该组件提供了一个SimpleCacheManager,但可以使用自定义缓存管理器代替默认的缓存管理器,并且必须实现CacheManagerInterface。
键生成
键生成由开发者决定,但为了方便,该组件自带了一些键生成逻辑。
注意:在基于注解的缓存中使用时,使用键生成器是强制性的。
默认情况下,该组件提供了一个SimpleHashKeyGenerator,它基本上使用md5算法对每个参数进行编码,并返回结果的md5散列。
出于测试目的,您还可以使用LiteralKeyGenerator,它构建类似slug的键。
注意:这两个生成器不支持非标量键,如对象。
您可以通过在config.yml
中设置key_generator
键来覆盖键生成器。
允许的值是:simple_hash
、literal
或自定义键生成器服务的ID
自定义键生成
可以使用自定义键生成器代替默认的键生成器,并且必须实现KeyGeneratorInterface。
TTL 策略
由于此组件提供缓存抽象,并非所有缓存提供程序都支持或以相同的方式处理TTL,因此必须在每个缓存配置选项中定义TTL策略(当支持选项时)。
示例
tbbc_cache: annotations: { enabled: true } manager: simple_cache cache: products: type: memcached ttl: 86400 # 1 day servers: memcached-01: { host: localhost, port: 11211 } user_feeds: type: memcached ttl: 0 # infinite (same as omitting the option) followers_list: type: apc ttl: 1296000 # 15 days activity_counters: type: redis ttl: 3600 # 1 hour server: host: 127.0.0.1 port: 6379
Symfony debug toolbar 集成
调试缓存操作往往很痛苦。为了方便这项工作,该组件直接在Symfony调试工具栏中添加了一些有用的实时信息。
以下是一些关于它将显示的信息的截图
已知限制
带有“allEntries”选项的缓存清除操作
由于缓存在Doctrine中的管理方式,尤其是在不同的缓存系统中处理的方式,使用带有“allEntries”选项的“CacheEvict”操作可能会导致不良行为。
警告:如果您使用不同的缓存命名空间但属于同一缓存实例(例如单个memcached服务器),则“allEntries”选项将清除所有命名空间中的所有缓存条目。这意味着它将清除整个实例的缓存。
Doctrine实体缓存
目前不支持自动缓存Doctrine实体。如果您需要缓存实体,您必须实现自己的逻辑。
实现这一点的 一种方法是通过覆盖注解和元数据来添加一个序列化“类型”选项,然后通过挂钩缓存事件来手动管理序列化/反序列化操作。
<?php namespace My\EventListener; use My\CacheBundle\SerializedCacheValue; use Tbbc\CacheBundle\Event\CacheHitEvent; use Tbbc\CacheBundle\Event\CacheUpdateEvent; use JMS\SerializerBundle\Serializer\SerializerInterface; use Tbbc\CacheBundle\Cache\CacheManagerInterface; class CacheEventListener { private $serializer; private $cacheManager; public function __construct(SerializerInterface $serializer, CacheManagerInterface $cacheManager) { $this->serializer = $serializer; $this->cacheManager = $cacheManager; } public function onAfterCacheHit(CacheHitEvent $event) { $value = $event->getValue(); if ($value instanceof SerializedCacheValue) { $value = $this->serializer->deserialize($value->data, $value->type, 'json'); $event->setValue($value); } } public function onAfterCacheUpdate(CacheUpdateEvent $event) { $cache = $event->getCache(); $key = $event->getKey(); $metadata = $event->getMetadata(); if (null !== $metadata->type) { $serializedValue = $this->serializer->serialize($event->getValue(), 'json'); $value = new SerializedCacheValue($metadata->type, $serializedValue); $this->cacheManager->getCache($cache)->set($key, $value); } } }
测试
安装开发依赖项
$ composer install --dev
运行测试套件
$ vendor/bin/phpunit
许可
此组件采用MIT许可。请参阅组件中的完整许可协议
Resources/meta/LICENSE