关于缓存

关于缓存

缓存是实际工作中非常常用的一种提高性能的方法。而在java中,所谓缓存,就是将程序或系统经常要调用的对象存在内存中,再次调用时可以快速从内存中获取对象,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

在增删改查中,数据库查询占据了数据库操作的80%以上,而非常频繁的磁盘I/O读取操作,会导致数据库性能极度低下。而数据库的重要性就不言而喻了:

  • 数据库通常是企业应用系统最核心的部分
  • 数据库保存的数据量通常非常庞大
  • 数据库查询操作通常很频繁,有时还很复杂

在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存


spring cache特性与缺憾

现在市场上主流的缓存框架有ehcache、redis、memcached。spring cache可以通过简单的配置就可以搭配使用起来。其中使用注解方式是最简单的。



Cache注解


从以上的注解中可以看出,虽然使用注解的确方便,但是缺少灵活的缓存策略,

缓存策略:

  • TTL(Time To Live ) 存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)
  • TTI(Time To Idle) 空闲期,即一个数据多久没被访问将从缓存中移除的时间

项目中可能有很多缓存的TTL不相同,这时候就需要编码式使用编写缓存。

条件缓存

根据运行流程,如下@Cacheable将在执行方法之前( #result还拿不到返回值)判断condition,如果返回true,则查缓存;

代码
  1. @Cacheable(value = "user", key = "#id", condition = "#id lt 10")    
  2. public User conditionFindById(final Long id)  


如下@CachePut将在执行完方法后(#result就能拿到返回值了)判断condition,如果返回true,则放入缓存

代码
  1. @CachePut(value = "user", key = "#id", condition = "#result.username ne 'zhang'")    
  2. public User conditionSave(final User user)  


如下@CachePut将在执行完方法后(#result就能拿到返回值了)判断unless,如果返回false,则放入缓存;(即跟condition相反)

代码
  1. @CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'")    
  2. public User conditionSave2(final User user)  


如下@CacheEvict, beforeInvocation=false表示在方法执行之后调用(#result能拿到返回值了);且判断condition,如果返回true,则移除缓存;

代码
  1. @CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'")   
  2. public User conditionDelete(final User user)  


小试牛刀,综合运用:

代码
  1. @CachePut(value = "user", key = "#user.id")  
  2.    public User save(User user) {  
  3.        users.add(user);  
  4.        return user;  
  5.    }  
  6.   
  7.    @CachePut(value = "user", key = "#user.id")  
  8.    public User update(User user) {  
  9.        users.remove(user);  
  10.        users.add(user);  
  11.        return user;  
  12.    }  
  13.   
  14.    @CacheEvict(value = "user", key = "#user.id")  
  15.    public User delete(User user) {  
  16.        users.remove(user);  
  17.        return user;  
  18.    }  
  19.   
  20.    @CacheEvict(value = "user", allEntries = true)  
  21.    public void deleteAll() {  
  22.        users.clear();  
  23.    }  
  24.   
  25.    @Cacheable(value = "user", key = "#id")  
  26.    public User findById(final Long id) {  
  27.        System.out.println("cache miss, invoke find by id, id:" + id);  
  28.        for (User user : users) {  
  29.            if (user.getId().equals(id)) {  
  30.                return user;  
  31.            }  
  32.        }  
  33.        return null;  
  34.    }  


配置ehcache与redis
spring cache集成ehcache,spring-ehcache.xml主要内容:

代码
  1. <dependency>  
  2.     <groupId>net.sf.ehcache</groupId>  
  3.     <artifactId>ehcache-core</artifactId>  
  4.     <version>${ehcache.version}</version>  
  5. </dependency>  

 

代码
  1. <!-- Spring提供的基于的Ehcache实现的缓存管理器 -->  
  2.       
  3. <!-- 如果有多个ehcacheManager要在bean加上p:shared="true" -->  
  4. <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
  5.      <property name="configLocation" value="classpath:xml/ehcache.xml"/>  
  6. </bean>  
  7.       
  8. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">  
  9.      <property name="cacheManager" ref="ehcacheManager"/>  
  10.      <property name="transactionAware" value="true"/>  
  11. </bean>  
  12.       
  13. <!-- cache注解,和spring-redis.xml中的只能使用一个 -->  
  14. <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>  


spring cache集成redis,spring-redis.xml主要内容:

代码
  1. <dependency>  
  2.     <groupId>org.springframework.data</groupId>  
  3.     <artifactId>spring-data-redis</artifactId>  
  4.     <version>1.8.1.RELEASE</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>org.apache.commons</groupId>  
  8.     <artifactId>commons-pool2</artifactId>  
  9.     <version>2.4.2</version>  
  10. </dependency>  
  11. <dependency>  
  12.     <groupId>redis.clients</groupId>  
  13.     <artifactId>jedis</artifactId>  
  14.     <version>2.9.0</version>  
  15. </dependency>  

 

代码
  1. <!-- 注意需要添加Spring Data Redis等jar包 -->  
  2. <description>redis配置</description>  
  3.   
  4. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
  5.     <property name="maxIdle" value="${redis.pool.maxIdle}"/>  
  6.     <property name="maxTotal" value="${redis.pool.maxActive}"/>  
  7.     <property name="maxWaitMillis" value="${redis.pool.maxWait}"/>  
  8.     <property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>  
  9.     <property name="testOnReturn" value="${redis.pool.testOnReturn}"/>  
  10. </bean>  
  11.   
  12. <!-- JedisConnectionFactory -->  
  13. <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
  14.     <property name="hostName" value="${redis.master.ip}"/>  
  15.     <property name="port" value="${redis.master.port}"/>  
  16.     <property name="poolConfig" ref="jedisPoolConfig"/>  
  17. </bean>  
  18.   
  19. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"  
  20.       p:connectionFactory-ref="jedisConnectionFactory">  
  21.     <property name="keySerializer">  
  22.         <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>  
  23.     </property>  
  24.     <property name="valueSerializer">  
  25.         <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
  26.     </property>  
  27.     <property name="hashKeySerializer">  
  28.         <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
  29.     </property>  
  30.     <property name="hashValueSerializer">  
  31.         <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
  32.     </property>  
  33. </bean>  
  34.   
  35. <!--spring cache-->  
  36. <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"  
  37.       c:redisOperations-ref="redisTemplate">  
  38.     <!-- 默认缓存10分钟 -->  
  39.     <property name="defaultExpiration" value="600"/>  
  40.     <property name="usePrefix" value="true"/>  
  41.     <!-- cacheName 缓存超时配置,半小时,一小时,一天 -->  
  42.     <property name="expires">  
  43.         <map key-type="java.lang.String" value-type="java.lang.Long">  
  44.             <entry key="halfHour" value="1800"/>  
  45.             <entry key="hour" value="3600"/>  
  46.             <entry key="oneDay" value="86400"/>  
  47.             <!-- shiro cache keys -->  
  48.             <entry key="authorizationCache" value="1800"/>  
  49.             <entry key="authenticationCache" value="1800"/>  
  50.             <entry key="activeSessionCache" value="1800"/>  
  51.         </map>  
  52.     </property>  
  53. </bean>  
  54. <!-- cache注解,和spring-ehcache.xml中的只能使用一个 -->  
  55. <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>  


项目中注解缓存只能配置一个,所以可以通过以下引入哪个配置文件来决定使用哪个缓存。
当然,可以通过其他配置搭配使用两个缓存机制。比如ecache做一级缓存,redis做二级缓存。


更加详细的使用与配置,可以参考项目中spring-shiro-training中有关spring cache的配置。

<think>我们正在讨论React Native中的缓存使用。根据用户的问题,他想了解ReactNative中缓存的使用方法。我们将结合引用内容,提供一份指南。引用中提到了几个与缓存相关的库:react-native-img-cache(引用1)、react-native-http-cache(引用2)、react-native-rn-cacheimage(引用3)、react-native-cached-image和react-native-fast-image(引用4)以及清除缓存的方法(引用5)。我们将从以下几个方面进行介绍:1.图片缓存2. HTTP缓存3.缓存清除注意:引用内容中提供的项目地址和代码片段将作为参考。首先,图片缓存是React Native中常见的需求,因为图片加载对性能影响较大。官方Image组件的缓存功能在iOS上支持,但Android上不够完善,因此通常使用第三方库。一、图片缓存1.使用react-native-fast-image(推荐,因为引用4提到它比较流行,且支持iOS和Android)安装:npminstall react-native-fast-image然后链接(对于旧版本RN,新版本自动链接)使用示例:importFastImagefrom 'react-native-fast-image'<FastImagestyle={{width:200, height:200 }}source={{uri:'https://example.com/image.jpg',priority: FastImage.priority.normal,cache:FastImage.cacheControl.immutable, //缓存策略}}resizeMode={FastImage.resizeMode.contain}/>2.使用react-native-cached-image(引用4提到)安装:npm installreact-native-cached-image注意:这个库可能已经不再维护,但我们可以给出基本用法。使用示例:import{ CachedImage} from'react-native-cached-image';<CachedImagesource={{uri:'https://example.com/image.jpg'}}style={{width:100, height:100 }}/>3.使用react-native-rn-cacheimage(引用3)这个库提供了CacheImage和AnimatedCacheImage组件,并且需要注册和注销。安装:npm installreact-native-rn-cacheimage在应用入口注册(如App.js):import{ CacheHelper }from "react-native-rn-cacheimage";...在组件中componentDidMount() {CacheHelper.register({overwrite:false}).catch(e=> console.log(e))}componentWillUnmount() {CacheHelper.unregister().catch(e=>console.log(e))}然后使用:import {CacheImage} from"react-native-rn-cacheimage";<CacheImagesource={{uri: 'https://example.com/image.jpg'}}style={{width:100,height:100}}/>二、HTTP缓存(用于网络请求,如API数据)引用2提到了react-native-http-cache,但该库可能已不再维护。我们可以使用其他库如react-native-fetch-blob(已更名为rn-fetch-blob)或axios结合本地存储来实现。另一种思路是使用react-native-http-cache(如果项目需要):安装:npm installreact-native-http-cache然后链接(react-native linkreact-native-http-cache)使用:import {clearHttpCache} from'react-native-http-cache';//清除HTTP缓存clearHttpCache().then(() =>console.log('Cachecleared'));但是,更常见的做法是使用AsyncStorage或者更强大的缓存库(如react-native-cache-store)来缓存API数据。三、清除缓存1.开发时清除Metro缓存:使用npm start-- --reset-cache(注意两个--,引用5指出常见错误是只写一个--)2.清除图片缓存:根据使用的图片缓存库提供的方法。例如,react-native-fast-image提供了清除缓存的方法:import FastImage from'react-native-fast-image'FastImage.clearDiskCache();//清除磁盘缓存FastImage.clearMemoryCache(); //清除内存缓存3.清除HTTP缓存:如上所述,可以使用react-native-http-cache的clearHttpCache方法。四、其他缓存对于API数据,我们可以使用redux-persist来将Redux状态持久化到本地存储,从而实现缓存。总结:根据需求选择合适的缓存库。图片缓存推荐使用react-native-fast-image,因为它维护较好且功能强大。HTTP缓存可以使用react-native-http-cache,但注意其维护状态。对于数据缓存,可以使用AsyncStorage或redux-persist。注意:使用缓存时要注意缓存的更新策略,避免数据过期。相关问题:1.React Native中如何实现离线缓存?2.如何管理React Native中的缓存大小?3.在ReactNative中,如何检查缓存是否生效?4.使用缓存时有哪些常见的坑?5. ReactNative中如何实现缓存数据的自动更新?</think>### React Native 缓存使用指南 在 React Native 开发中,缓存技术能显著提升应用性能,减少网络请求并优化用户体验。以下是核心缓存方案及实现方法: #### 一、图片缓存方案 1. **react-native-fast-image**(推荐方案) 高性能图片缓存库,支持 iOS/Android 双平台: ```jsx import FastImage from 'react-native-fast-image'; <FastImage style={{ width: 100, height: 100 }} source={{ uri: 'https://example.com/image.jpg', cache: FastImage.cacheControl.immutable, // 永久缓存 }} /> ``` - 特性:磁盘/内存双缓存、预加载、优先级控制 - 清除缓存: ```javascript FastImage.clearDiskCache(); // 清除磁盘缓存 FastImage.clearMemoryCache(); // 清除内存缓存 ``` 2. **react-native-rn-cacheimage**(引用[^3]) 需全局注册缓存管理器: ```jsx import { CacheHelper, CacheImage } from "react-native-rn-cacheimage"; // 应用入口注册 componentDidMount() { CacheHelper.register({ overwrite: false }); } // 组件使用 <CacheImage source={{ uri: "https://example.com/photo.png" }} style={styles.image} /> ``` #### 二、HTTP 请求缓存 1. **react-native-http-cache**(引用[^2]) 管理网络请求缓存: ```javascript import * as CacheManager from 'react-native-http-cache'; // 获取缓存大小 CacheManager.getHttpCacheSize().then(size => console.log(size)); // 清除HTTP缓存 CacheManager.clearHttpCache(); ``` #### 三、开发环境缓存管理 - **重置 Metro 打包缓存**(引用[^5]) 修改代码后未生效时使用: ```bash npm start -- --reset-cache # 注意两个"--" ``` #### 四、缓存策略选择建议 | 场景 | 推荐方案 | 优势 | |---------------------|-----------------------------|------------------------------| | 频繁加载的网络图片 | react-native-fast-image | 高性能、自动过期管理 | | 静态资源缓存 | react-native-rn-cacheimage | 精细控制覆盖策略 | | API 数据缓存 | react-native-http-cache | 减少重复网络请求 | | 开发环境热更新失效 | Metro reset-cache | 解决打包缓存问题 | #### 五、最佳实践 1. **缓存过期策略** 动态内容设置合理过期时间(如 FastImage 的 `cacheControl.cacheOnly`) 2. **缓存大小监控** 定期清理过期缓存,避免存储占用过大 3. **离线优先策略** 结合 `NetInfo` 实现无网络时读取缓存 > 注意:官方 `Image` 组件的 `cache` 属性仅支持 iOS(引用[^4]),Android 需使用第三方库。 --- ### 相关问题 1. React Native 中如何实现磁盘缓存和内存缓存的优先级控制? 2. 使用 `react-native-fast-image` 时如何自定义缓存过期时间? 3. 如何监控 React Native 应用的缓存使用情况? 4. 在离线场景下如何保证缓存数据的有效性? 5. 不同缓存库(如 FastImage 与 rn-cacheimage)的性能对比指标有哪些? [^1]: React Native 图片缓存项目教程 [^2]: react native 清除缓存 [^3]: React Native图片缓存组件react-native-rn-cacheimage [^4]: React Native的缓存和下载 [^5]: React-Native清除缓存汇总
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值