spring用单例模型做高速缓存

合集下载

使用@CacheEvict清除指定下所有缓存

使用@CacheEvict清除指定下所有缓存

使⽤@CacheEvict清除指定下所有缓存⽬录@CacheEvict清除指定下所有缓存@Cacheable 缓存 @CachePut:缓存更新 @CacheEvict:缓存删除@Cacheable 缓存@CachePut:缓存更新@CacheEvict:缓存删除@CacheEvict清除指定下所有缓存@CacheEvict(cacheNames = "parts:grid",allEntries = true)此注解会清除part:grid下所有缓存@CacheEvict要求指定⼀个或多个缓存,使之都受影响。

此外,还提供了⼀个额外的参数allEntries 。

表⽰是否需要清除缓存中的所有元素。

默认为false,表⽰不需要。

当指定了allEntries为true时,Spring Cache将忽略指定的key。

有的时候我们需要Cache⼀下清除所有的元素。

@Cacheable 缓存 @CachePut:缓存更新 @CacheEvict:缓存删除@Cacheable 缓存说明:在⽀持Spring Cache的环境下,对于使⽤@Cacheable标注的⽅法,Spring在每次执⾏前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执⾏该⽅法,⽽是直接从缓存中获取结果进⾏返回,否则才会执⾏并将返回结果存⼊指定的缓存中。

// @since 3.1 可以标注在⽅法上、类上下同@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Cacheable {// 缓存名称可以写多个,key的真正组成,以cacheName为前缀,多个就会有多个key产⽣@AliasFor("cacheNames")String[] value() default {};@AliasFor("value")String[] cacheNames() default {};// ⽀持写SpEL,切可以使⽤#root,#参数名”或者“#p参数index”//详情去 https:///dalong_bamboo/article/details/103844076String key() default "";// Mutually exclusive:它和key属性互相排斥。

Spring的并发问题——有状态Bean和无状态Bean

Spring的并发问题——有状态Bean和无状态Bean

Spring的并发问题——有状态Bean和⽆状态Bean⼀、有状态和⽆状态有状态会话bean :每个⽤户有⾃⼰特有的⼀个实例,在⽤户的⽣存期内,bean保持了⽤户的信息,即“有状态”;⼀旦⽤户灭亡(调⽤结束或实例结束),bean的⽣命期也告结束。

即每个⽤户最初都会得到⼀个初始的bean。

简单来说,有状态就是有数据存储功能。

有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是⾮线程安全的。

⽆状态会话bean :bean⼀旦实例化就被加进会话池中,各个⽤户都可以共⽤。

即使⽤户已经消亡,bean 的⽣命期也不⼀定结束,它可能依然存在于会话池中,供其他⽤户调⽤。

由于没有特定的⽤户,那么也就不能保持某⼀⽤户的状态,所以叫⽆状态bean。

但⽆状态会话bean 并⾮没有状态,如果它有⾃⼰的属性(变量),那么这些变量就会受到所有调⽤它的⽤户的影响,这是在实际应⽤中必须注意的。

简单来说,⽆状态就是⼀次操作,不能保存数据。

⽆状态对象(Stateless Bean),就是没有实例变量的对象 .不能保存数据,是不变类,是线程安全的。

package com.sw;public class TestManagerImpl implements TestManager{private User user; //有⼀个记录信息的实例public void deleteUser(User e) throws Exception {user = e ; //1prepareData(e);}public void prepareData(User e) throws Exception {user = getUserByID(e.getId()); //2.....//使⽤user.getId(); //3..........}}⼀个有状态的bean⼆、解决有状态bean的线程安全问题Spring对bean的配置中有四种配置⽅式,我们只说其中两种:singleton单例模式、prototype原型模式。

cacheable注解获取方法中的参数

cacheable注解获取方法中的参数

Cacheable 注解获取方法中的参数本文介绍了在使用 Cacheable 注解进行方法缓存时,注解中的参数有哪些,以及这些参数的作用和使用方法。

在 Java 中,为了提高方法的执行效率,可以使用缓存技术,将方法的返回结果存储在内存中,下次再调用该方法时,直接从缓存中取出结果即可,避免了重复计算的开销。

在 Spring 框架中,可以使用 Cacheable 注解来实现方法缓存。

Cacheable 注解可以应用于方法或类上,用于配置缓存策略。

在 Cacheable 注解中,有一些参数是用来指定缓存策略的,下面我们来看看这些参数的具体用法。

1. cacheName 参数cacheName 参数用于指定缓存的名称,它是一个必填参数。

缓存的名称必须是唯一的,否则会导致缓存冲突。

可以使用“default”作为缓存名称,表示使用默认缓存。

2. cacheMode 参数cacheMode 参数用于指定缓存的模式,它用于控制缓存的可见性。

cacheMode 参数可以是以下三个值之一:- READ_ONLY:缓存只读,不能修改。

- READ_WRITE:缓存可读写,可以修改。

- UPDATE_NOT_CACHEABLE:缓存不可更新,每次调用方法都会重新计算结果。

3. cacheConcurrencyStrategy 参数cacheConcurrencyStrategy 参数用于指定缓存的并发策略。

它可以是以下两个值之一:- Absolute:使用绝对缓存并发策略,即每个线程都有自己的缓存。

- Protocol:使用协议缓存并发策略,即多个线程共享同一个缓存,但是每个线程都有自己的数据区。

4. cacheExceptionInvoker 参数cacheExceptionInvoker 参数用于指定缓存异常处理器,它用于处理缓存异常。

当缓存异常发生时,可以使用该处理器来执行异常处理逻辑。

5. cacheSeconds 参数cacheSeconds 参数用于指定缓存的有效期限,它表示缓存中的数据在多长时间内有效。

前端框架中实现页面缓存与状态管理的技巧

前端框架中实现页面缓存与状态管理的技巧

前端框架中实现页面缓存与状态管理的技巧在前端开发中,页面缓存和状态管理是两个非常重要的概念。

页面缓存可以提高页面加载速度和用户体验,而状态管理则可以帮助我们更好地管理应用程序的状态。

本文将介绍一些前端框架中实现页面缓存和状态管理的技巧。

一、页面缓存技巧1. LocalStorage和SessionStorageLocalStorage和SessionStorage是HTML5提供的两个本地存储对象,它们可以将数据在浏览器中进行长期(LocalStorage)或会话(SessionStorage)级别的保存。

我们可以使用这两个对象来存储页面中需要缓存的数据,以便在页面刷新或重新加载时快速恢复页面状态。

2. 缓存组件的渲染结果在一些前端框架中,我们可以将组件的渲染结果缓存起来,以便在需要重新加载页面时快速渲染。

这种技巧通常在页面内容不经常变化的情况下使用,可以有效地减少页面的加载时间。

3. 路由缓存在使用前端框架的单页面应用程序中,路由是非常重要的。

通过路由缓存技巧,我们可以将已经加载的组件和页面缓存起来,以便在切换路由时快速展示之前的页面。

这种技巧可以提高用户的操作流畅度和页面响应速度。

二、状态管理技巧1. 全局状态管理在前端开发中,应用程序的状态通常被分散在各个组件中。

为了更好地管理这些状态,可以引入全局状态管理工具,例如Redux、Vuex等。

全局状态管理通过将应用程序的状态集中存储,并通过分发动作来触发状态的改变,可以帮助我们更好地管理应用程序的状态和数据。

2. 局部状态管理除了全局状态管理,有些状态只对某个组件或页面有效,而不需要影响整个应用程序的状态。

在这种情况下,可以使用组件库中提供的局部状态管理功能,例如Vue中的data或React中的useState。

通过局部状态管理,我们可以将特定组件或页面中的状态和数据与其他组件或页面隔离开来,提高代码的可维护性和复用性。

3. 路由参数和查询参数在一些情况下,我们可以利用路由参数和查询参数来传递和管理页面的状态信息。

Spring注解【非单例】

Spring注解【非单例】

Spring注解【⾮单例】花了⾄少⼀整天的时间解决了这个问题,必须记录这个纠结的过程,问题不可怕,思路很绕弯。

为了能说清楚⾃⼰的问题,我都⽤例⼦来模拟。

我有⼀个类MyThread是这样的:1 @Service2public class MyThread extends Thread {3 @Autowired4 MyService myService;5 ......6 }在主线程中有这样⼀个调⽤:1 @Autowired2 MyThread myThread;3 ......4public void invoke{5if(condition){6 myThread.start();7 }8 }9 ......我的invoke存在⼀个循环调⽤,此时遇到了第⼀个问题!问题⼀:抛出ng.IllegalThreadStateException。

问题⼀的解决:1//@Autowired2//MyThread myThread;3 ......4public void invoke {5if(condition){6 //myThread.start();6 MyThread myThread = new MyThread();7 myThread.start();8 }9 }引发的新的问题!问题⼆:我⽤了Spring注解,⽤new的话⽆法⽤注解实现注⼊,所以myThread中的myService对象抛出空指针。

问题⼆的解决:放弃了MyThread类,新写了⼀个类,开始绕弯。

1 @Service2public class MyRunable implements Runnable {3 @Autowired4 MyService myService;5 ......6 }相应的,修改主线程中的调⽤。

1//@Autowired2//MyThread myThread;3 @Autowired4 MyRunnable myRunnable;5 ......6public void invoke{7if(condition){8//MyThread myThread = new MyThread();9//myThread.start();10 Thread t = new Thread(myRunnable);11 t.start();12 }13 }14 ......⼜遇到了新的问题!我需要对myRunnable线程命名。

Java中的缓存技术

Java中的缓存技术

Java中的缓存技术缓存技术在软件开发中起着至关重要的作用。

它可以提高系统性能、降低对底层资源的访问频率,从而减轻服务器负载并改善用户体验。

在Java开发中,有许多可供选择的缓存技术。

本文将介绍几种常见的Java缓存技术,以及它们的应用场景和原理。

一、内存缓存内存缓存是最常见的缓存技术之一,它将数据保存在内存中,以提高读取速度。

在Java中,可以使用集合框架中的Map接口的实现类来实现内存缓存,如HashMap、ConcurrentHashMap等。

这些类提供了快速的Key-Value存储,通过Key快速查找对应的Value,以实现快速访问缓存数据。

内存缓存适用于数据读取频繁但不经常更新的场景,例如字典数据、配置信息等。

需要注意的是,内存缓存的容量是有限的,当缓存数据超过容量限制时,需要采取一些策略来处理,如LRU(最近最少使用)算法将最久未访问的数据移出缓存。

二、分布式缓存分布式缓存是一种将数据存储在多台服务器节点上的缓存技术。

Java中有多种分布式缓存框架可供选择,如Redis、Memcached等。

这些框架提供了高性能、可扩展的分布式缓存服务,可以在集群中存储大量的数据,并提供分布式缓存的管理和查询接口。

分布式缓存适用于需要同时服务大量客户端并具有高并发读写需求的场景,例如电商网站的商品信息、社交网络的用户数据等。

通过将数据存储在多台服务器上,可以提高系统的可用性和扩展性。

三、页面缓存页面缓存是将网页内容保存在缓存中,以减少对数据库或后端服务的访问频率,从而提高页面的加载速度。

在Java中,可以通过使用Web服务器或反向代理服务器的缓存功能,例如Nginx、Varnish等,来实现页面缓存。

页面缓存适用于内容相对静态或者不经常变化的场景,例如新闻网站的文章、博客网站的页面等。

通过将网页内容保存在缓存中,可以避免每次请求都重新生成页面,大大提高响应速度和系统的并发能力。

四、数据库缓存数据库缓存是将数据库查询结果保存在缓存中,以减少对数据库的频繁查询,提高系统的响应速度和并发能力。

ehcache基本原理

ehcache基本原理Ehcache的类层次模型主要为三层,最上层的是CacheManager,他是操作Ehcache的⼊⼝。

我们可以通过CacheManag er.getInstance()获得⼀个单个的CacheManager,或者通过CacheManager的构造函数创建⼀个新的CacheManager。

每个Ca cheManager都管理着多个Cache。

⽽每个Cache都以⼀种类Hash的⽅式,关联着多个Elemenat。

⽽Element则是我们⽤于存放要缓存内容的地⽅。

ehcache的刷新策略ehcache的刷新策略是当缓存在放⼊的时候记录⼀个放⼊时间,它是⽤Lazy Evict的⽅式,在取的时候同设置的TTL⽐较ehcache缓存的3种清空策略:1 FIFO,先进先出2 LFU,最少被使⽤,缓存的元素有⼀个hit属性,hit值最⼩的将会被清出缓存。

3 LRU,最近最少使⽤的,缓存的元素有⼀个时间戳,当缓存容量满了,⽽⼜需要腾出地⽅来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

事件处理可以为CacheManager添加事件监听,当对CacheManager增删Cache时,事件处理器将会得到通知。

要配置事件处理,需要通过ehcache的配置⽂件来完成。

可以为Cache添加事件监听,当对Cache增删Element时,事件处理器将会得到通知。

要配置事件处理,需要通过ehcache的配置⽂件来完成。

ehcache参数配置:maxInMemory - 设定内存中创建对象的最⼤值。

eternal - 设置元素(译注:内存中对象)是否永久驻留。

如果是,将忽略超时限制且元素永不消亡。

timeToIdleSeconds - 设置某个元素消亡前的停顿时间。

也就是在⼀个元素消亡之前,两次访问时间的最⼤时间间隔值。

这只能在元素不是永久驻留时有效(译注:如果对象永恒不灭,则设置该属性也⽆⽤)。

SpringBoot@CacheableRedis设置缓存过期时间

SpringBoot@CacheableRedis设置缓存过期时间1.x 设置@Bean@Primarypublic CacheManager cacheManager(RedisTemplate redisTemplate) {RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);Map<String, Long> expires = new HashMap<>();expires.put("timeout", 60L);// 设置超时// 根据特定名称设置有效时间redisCacheManager.setExpires(expires);// 设置默认的时间redisCacheManager.setDefaultExpiration(cacheDefaultExpiration);return redisCacheManager;}使⽤⽅式:转载:传送门@Configuration//@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600 * 12)//最⼤过期时间@EnableCachingpublic class RedisConfig {@Beanpublic CacheManager cacheManager(RedisTemplate redisTemplate) {RedisCacheManager rcm = new RedisCacheManager(redisTemplate);//设置缓存过期时间Map<String, Long> expires = new HashMap<>();expires.put("12h", 3600 * 12L);expires.put("1h", 3600 * 1L);expires.put("10m", 60 * 10L);rcm.setExpires(expires);// rcm.setDefaultExpiration(60 * 60 * 12);//默认过期时间return rcm;}}//----------------------------------------------------------@Cacheable(value = "12h", key = "#root.methodName")@Overridepublic List<User> getUserArticleRank() {//获得排⾏榜前10名的⽤户,每12⼩时刷新⼀次return userRepository.findTop10ByArticleSize();}2.x 设置转载:传送门/*** 2.XX版本的配置**/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // ⽣成⼀个默认配置,通过config对象即可对缓存进⾏⾃定义配置config = config.entryTtl(Duration.ofMinutes(2)) // 设置缓存的默认过期时间,也是使⽤Duration设置.disableCachingNullValues(); // 不缓存空值// 设置⼀个初始化的缓存空间set集合Set<String> cacheNames = new HashSet<>();cacheNames.add("catalog_test_id");cacheNames.add("catalog_test_name");// 对每个缓存空间应⽤不同的配置Map<String, RedisCacheConfiguration> configMap = new HashMap<>();configMap.put("catalog_test_id", config);configMap.put("catalog_test_name", config.entryTtl(Duration.ofMinutes(5)));RedisCacheManager cacheManager = RedisCacheManager.builder(factory) // 使⽤⾃定义的缓存配置初始化⼀个cacheManager .initialCacheNames(cacheNames) // 注意这两句的调⽤顺序,⼀定要先调⽤该⽅法设置初始化的缓存名,再初始化相关的配置.withInitialCacheConfigurations(configMap).build();return cacheManager;}@CacheConfig(cacheNames = "catalog_test_name")public class SsoCache{@Cacheable(keyGenerator = "wiselyKeyGenerator")public String getTokenByGsid(String gsid)}-------------------------------------使⽤(name中增加“#”,后⾯是过期时间,不加则⾛默认时间)@Cacheable(cacheNames = "catalog_test_name#120", unless = "#result==null")public UserEntity findUserByUserName(String userName) {return userRepository.findUserByUserName(userName);}转⾃:https:///qq_28114159/article/details/106098180。

EhCache缓存系统的使用

EhCache缓存系统的使用在Web开发中,缓存系统的应用能极大提高系统的响应速度,其中在Java应用中EhCache是比较常用的一个缓存框架。

EhCache是一个纯Jvm进程内的缓存框架,具有快速轻量、配置简单、功能强大等特点,是Hibernate中的默认CacheProvider。

下图是EhCache 的基本架构:EhCache的基本模块提供了缓存的实现,包括缓存管理器、多种的缓存策略、缓存的存储及相关扩展和控制接口,Replication模块提供了多种的分布式缓存的实现,两个APIs接口模块并且提供了基于J2EE技术相关的API。

EhCache的使用EhCache的基本包是ehcache-core-$ver.jar,依赖包是SLF4J,可以通过代码配置也可以使用配置文件,基本的元素有:CacheManager,缓存管理器,管理一组缓存的实例;Cache,一个缓存的实例,是缓存存放的地方,实现缓存存取接口;Element,单条缓存的组成单位,有Key、Value两部分,这两部分需要实现Serializeable接口。

基本使用代码如下:CacheManager manager = CacheManager.newInstance("src/config/ehcache.xml");manager.addCache("testCache");Cache test = manager .getCache("testCache");test.put(new Element("key1", "value1"));Element result = test.get(“key1”);test.remove(“key1”);使用Spring框架的时候可以使用IOC简化CacheManager的获取:@Autowiredprivate Cache sysSymbolCache;配置文件的使用介绍:<ehcache xmlns:xsi="/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"monitoring="autodetect"><diskStore path="atoscache" /><defaultCache maxElementsInMemory="100000" eternal="false"timeToIdleSeconds="300" timeToLiveSeconds="720000" overflowToDisk="true"memoryStoreEvictionPolicy="LRU" /><cache name="sysSymbolCache" maxElementsInMemory="200000"eternal="false" overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="216000"timeToLiveSeconds="720000"memoryStoreEvictionPolicy="LFU"></cache></ehcache>diskStore代表存储的目录名,默认是java.io.tmpdir,defaultCache是默认的Cache配置。

cacheevict 原理

cacheevict 原理CacheEvict是Spring框架中的一种标注,用于在缓存中删除一个或多个条目。

它通常用于在数据修改时,清除与该数据有关联的缓存,以保证数据的准确性。

CacheEvict的工作原理如下:1. 当方法调用时,Spring框架首先检查缓存中是否已存在该方法的结果。

如果存在,则返回缓存中的值,而不是执行方法体。

2. 如果缓存中不存在该方法的结果,则调用方法执行体,将返回的结果放入缓存中。

3. 如果方法被标记为CacheEvict,那么在方法执行后,Spring框架会从缓存中删除该方法的结果。

具体来说,CacheEvict支持以下属性:value:指定缓存的名称,需要在Spring配置文件中进行定义。

可以设置多个缓存名称作为数组,表示清除多个缓存。

key:指定用于删除缓存条目的键,用SpEL表达式进行配置。

缺省情况下,Spring会使用方法的参数列表作为缓存条目的键。

如果需要自定义缓存键,可以通过这个属性进行设置。

condition:指定在何种情况下删除缓存条目,用SpEL表达式进行配置。

例如,可以通过设置“#result==null”来表示只有在方法返回值为null时才删除缓存条目。

allEntries:指定是否清除缓存中所有条目。

默认值为false,表示只删除与当前方法有关的缓存条目。

如果设置为true,那么将清除该缓存中的所有条目。

CacheEvict有助于提高系统性能和响应速度,可以使缓存与数据库保持同步。

它适用于对缓存数据要求较高的场景,例如金融交易系统、在线游戏等。

但需要注意的是,缓存清除也可能导致缓存雪崩和缓存穿透等问题,因此需要谨慎使用和合理配置。

总之,CacheEvict是Spring框架中常用的缓存清除标注,通过它可以方便地清除缓存条目,保证缓存数据的准确性和一致性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Spring高速缓存
先来一个单例模型,里面的重点是有一个map,可以获取内存空间。单例模型的话,可以自
己访问自己,内部数据,不会被垃圾回收机制回收。
@Component
public class AutoReplyCache {
private static HashMap cacheMap;
@Autowired
private AutoreplyListService autoreplyListService;
private static AutoReplyCache arcache;
private byte[] lock = new byte[0];
public static AutoReplyCache getInstance()
{
if(arcache== null)
{
arcache = new AutoReplyCache();
}
return arcache;
}

public AutoReplyCache(){

}
public synchronized void loadAll() {
System.out.println("====="+"得到缓存========");
cacheMap=new HashMap();
List arlistlist
=autoreplyListService.getList();
if(arlistlist != null){
setCacheMap(arlistlist);
}
System.out.println("==="+"得到缓存完毕=====");
}

public synchronized void reloadAll() {
System.out.println("===="+"重新得到缓存=====");
List arlistlist =
autoreplyListService.getList();
if(arlistlist != null){
cacheMap.clear();
setCacheMap(arlistlist);
}
System.out.println("===="+"重新得到缓存=====");
}

private void setCacheMap(List arlistlist) {
for (AutoreplyList arlist : arlistlist) {
cacheMap.put(String.valueOf(arlist.getNum()),arlist);
}
}
public synchronized void add(AutoreplyList arlist){
cacheMap.put(String.valueOf(arlist.getNum()),arlist);
}
public synchronized void update(AutoreplyList arlist) {
cacheMap.put(String.valueOf(arlist.getNum()), arlist);
}
public synchronized AutoreplyList findarlistByID(String id){
if(cacheMap.values()!=null && cacheMap.values().size()>0){
for (Iterator iter = cacheMap.values().iterator();
iter.hasNext();) {
AutoreplyList arlist = (AutoreplyList) iter.next();
if(id.equals(String.valueOf(arlist.getId()))){
return arlist;
}
}
}
return null;
}

public synchronized List getallCache(){
List listAll=new ArrayList();
ArrayList();
for (Iterator iter = cacheMap.values().iterator();
iter.hasNext();) {
AutoreplyList arlist = (AutoreplyList) iter.next();
listAll.add(arlist);
}
return listAll;

}

public void removeCusCache(AutoreplyList cus) {
synchronized (lock) {
cacheMap.remove(String.valueOf(cus.getId()));
}
}
}
然后是配置,在spring-servlet.xml中加下面这句话
init-method="loadAll" scope="singleton" >
其中loadAll是启动时所要开始的方法。Singleton是单例模型

最后说一下访问方法。
AutoReplyCache tmpcache=AutoReplyCache.getInstance();
List arlistlist =tmpcache.getallCache();
访问就很简单了,只是在增删改查数据的时候记得更新缓存,或者在增删改查之后,访问
reloadAll的方法,可以重新载入所有的数据。

相关文档
最新文档