当前位置: 首页 > news >正文

在四川省住房和城乡建设厅网站上查银徽seo

在四川省住房和城乡建设厅网站上查,银徽seo,平面广告设计培训班费用,网上的推广整体思路: 创建EnableLocalCache注解,用于选择是否开启本地缓存创建LocalCache注解和LocalCacheEvict注解用于缓存的构建、过期时间和清除切面实现缓存的获取、写入和清除SpEL表达式的支持缓存配置类,用于创建Bean对象开启定时任务清除过期的…

整体思路:

  1. 创建@EnableLocalCache注解,用于选择是否开启本地缓存
  2. 创建@LocalCache注解和@LocalCacheEvict注解用于缓存的构建、过期时间和清除
  3. 切面实现缓存的获取、写入和清除
  4. SpEL表达式的支持
  5. 缓存配置类,用于创建Bean对象
  6. 开启定时任务清除过期的缓存,支持自定义任务参数

项目示例Gitee地址: Java实现本地缓存demo

效果展示:


代码实现:

 1.引入基本依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.10</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.7.10</version>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version>
</dependency>

2.创建注解:

2.1 @EnableLocalCache 开启缓存,@Import(LocalCacheConfig.class)导入缓存配置类
package com.gooluke.localcache.annotation;import com.gooluke.localcache.config.LocalCacheConfig;
import org.springframework.context.annotation.Import;import java.lang.annotation.*;/*** @author gooluke* 开启本地缓存*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(LocalCacheConfig.class)
@Documented
public @interface EnableLocalCache {
}
2.2 @LocalCache 使用缓存
package com.gooluke.localcache.annotation;import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;/*** @author gooluke* 本地缓存注解*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LocalCache {/*** 缓存key* 支持SpEL表达式*/String key() default "";/*** 缓存过期时间 0-表示永不过期*/long timeout() default 0;/*** 缓存过期时间单位*/TimeUnit timeUnit() default TimeUnit.SECONDS;}
2.3 @LocalCacheEvict 清除缓存
package com.gooluke.localcache.annotation;import java.lang.annotation.*;/*** @author gooluke* 删除缓存注解*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LocalCacheEvict {/*** 要清除缓存的key* 支持SpEL表达式*/String key();}

3.切面类

3.1 LocalCacheAspect 缓存切面类
package com.gooluke.localcache.aop;import com.gooluke.localcache.annotation.LocalCache;
import com.gooluke.localcache.cache.LocalCacheManager;
import com.gooluke.localcache.utils.SpELUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;@Aspect
@AllArgsConstructor
@Slf4j
public class LocalCacheAspect {private final LocalCacheManager cacheManager;@Around("@annotation(localCache)")public Object cacheMethod(ProceedingJoinPoint joinPoint, LocalCache localCache) throws Throwable {// 获取方法签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取方法的返回类型Class<?> returnType = signature.getReturnType();// 获取方法的全路径限定名(包括包名、类名和方法名)String methodName = signature.getMethod().toString();// 构建缓存键String cacheKey = (localCache.key() != null && !localCache.key().isEmpty()) ? SpELUtil.parseSpEl(localCache.key(), joinPoint) : methodName;// 尝试从缓存中获取数据Object cachedValue = cacheManager.getCache(cacheKey);if (cachedValue != null) {// 如果缓存中有数据,则直接返回return returnType.cast(cachedValue); // 强制转换为方法的返回类型} else {long timeout = localCache.timeout();// 如果没有缓存,则执行目标方法Object proceed = joinPoint.proceed();// 将结果放入缓存if (timeout == 0) {cacheManager.addCache(cacheKey, proceed);} else {cacheManager.addCache(cacheKey, proceed, timeout, localCache.timeUnit());}return proceed;}}
}
3.2 LocalCacheEvictAspect 清除缓存的切面类
package com.gooluke.localcache.aop;import com.gooluke.localcache.annotation.LocalCacheEvict;
import com.gooluke.localcache.cache.LocalCacheManager;
import com.gooluke.localcache.utils.SpELUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;@Aspect
@AllArgsConstructor
@Slf4j
public class LocalCacheEvictAspect {private final LocalCacheManager cacheManager;@Around("@annotation(localCacheEvict)")public Object cacheMethod(ProceedingJoinPoint joinPoint, LocalCacheEvict localCacheEvict) throws Throwable {// 获取方法签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取方法的全路径限定名(包括包名、类名和方法名)String methodName = signature.getMethod().toString();// 构建缓存键String cacheKey = (localCacheEvict.key() != null && !localCacheEvict.key().isEmpty()) ? SpELUtil.parseSpEl(localCacheEvict.key(), joinPoint) : methodName;//删除缓存cacheManager.deleteCache(cacheKey);return joinPoint.proceed();}
}

4.SpEL工具类

package com.gooluke.localcache.utils;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.lang.reflect.Method;
import java.util.Optional;/*** @author gooluke* datetime 2024/12/5 19:19*/
public class SpELUtil {/*** 用于SpEL表达式解析*/private static final ExpressionParser parser = new SpelExpressionParser();/*** 解析、获取参数名*/private static final DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();public static String parseSpEl(String spEl, ProceedingJoinPoint joinPoint) {if (spEl == null || spEl.isEmpty()) {return "";}MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();Object[] args = joinPoint.getArgs();//这里是因为args里没有参数名,只有值,所以只能从DefaultParameterNameDiscoverer去获取参数名String[] params = Optional.ofNullable(parameterNameDiscoverer.getParameterNames(method)).orElse(new String[]{});EvaluationContext context = new StandardEvaluationContext();//el解析需要的上下文对象for (int i = 0; i < params.length; i++) {context.setVariable(params[i], args[i]);//所有参数都作为原材料扔进去-基于参数名称context.setVariable("p" + i, args[i]);//所有参数都作为原材料扔进去-基于参数位置}Expression expression = parser.parseExpression(spEl);return expression.getValue(context, String.class);}public static String getMethodKey(Method method) {return method.getDeclaringClass() + "#" + method.getName();}
}

5.缓存管理类LocalCacheManager&&缓存对象LocalCacheItem

5.1 LocalCacheManager 缓存管理器
package com.gooluke.localcache.cache;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;public class LocalCacheManager {private static final Logger log = LoggerFactory.getLogger(LocalCacheManager.class);private final Map<String, LocalCacheItem<Object>> cacheMap = new ConcurrentHashMap<>();/*** 添加不过期缓存*/public void addCache(String name, Object object) {addCache(name, object, 0, null);}public void addCache(String name, Object object, long timeout, TimeUnit timeUnit) {if (name == null) {return;}cacheMap.put(name, new LocalCacheItem<>(object, timeout, timeUnit));}public void deleteCache(String name) {cacheMap.remove(name);}public Object getCache(String name) {if (name == null) {return null;}LocalCacheItem<Object> cache = cacheMap.getOrDefault(name, null);if (cache != null) {if (cache.isExpired()) {deleteCache(name);return null;} else {return cache.getValue();}}return null;}/*** 清理所有已过期的缓存项*/public void cleanupExpired() {try {log.info("清除前总缓存数量:" + cacheMap.size());// 移除过期的缓存项cacheMap.entrySet().removeIf(entry -> entry.getValue().isExpired());log.info("清除过期缓存后总缓存数量:" + cacheMap.size());} catch (Exception e) {log.error("定时清除本地缓存异常:", e);}}}
5.2 LocalCacheItem 本地缓存对象
package com.gooluke.localcache.cache;import lombok.Getter;import java.util.concurrent.TimeUnit;public class LocalCacheItem<T> {@Getterprivate final T value;private final long expiryTime; // 过期时间戳public LocalCacheItem(T value, long timeout, TimeUnit timeUnit) {this.value = value;this.expiryTime = timeout == 0 ? 0 : System.currentTimeMillis() + timeUnit.toMillis(timeout);}public boolean isExpired() {return expiryTime != 0 && System.currentTimeMillis() > expiryTime;}
}

6.缓存配置类LocalCacheConfig

package com.gooluke.localcache.config;import com.gooluke.localcache.aop.LocalCacheAspect;
import com.gooluke.localcache.aop.LocalCacheEvictAspect;
import com.gooluke.localcache.cache.LocalCacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class LocalCacheConfig implements ApplicationRunner, DisposableBean {private static final Logger log = LoggerFactory.getLogger(LocalCacheConfig.class);private final LocalCacheManager localCacheManager = new LocalCacheManager();private final ScheduledExecutorService CACHE_CLEANUP_SCHEDULER = Executors.newScheduledThreadPool(1);@Value("${cache.cleanup.initialDelay:0}")private long initialDelay;@Value("${cache.cleanup.period:60}")private long period;@Beanpublic LocalCacheAspect localCacheAspect() {return new LocalCacheAspect(this.localCacheManager);}@Beanpublic LocalCacheEvictAspect localCacheEvictAspect() {return new LocalCacheEvictAspect(this.localCacheManager);}@Overridepublic void run(ApplicationArguments args) throws Exception {log.info("CACHE_CLEANUP_SCHEDULER task initialDelay:{},period:{}", initialDelay, period);CACHE_CLEANUP_SCHEDULER.scheduleAtFixedRate(localCacheManager::cleanupExpired, initialDelay, period, TimeUnit.SECONDS);}@Overridepublic void destroy() throws Exception {log.info("关闭CACHE_CLEANUP_SCHEDULER");CACHE_CLEANUP_SCHEDULER.shutdown();}
}

7.主启动类开启本地缓存

package com.gooluke.localcache;import com.gooluke.localcache.annotation.EnableLocalCache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author gooluke*/
@SpringBootApplication
@EnableLocalCache//开启本地缓存
public class LocalCacheDemoApplication {public static void main(String[] args) {SpringApplication.run(LocalCacheDemoApplication.class, args);}}

8.支持配置定时清除过期缓存的任务参数,不配置默认延迟0s,间隔60s

#延迟启动
cache.cleanup.initialDelay=10
#缓存清理间隔
cache.cleanup.period=30

http://www.cadmedia.cn/news/16640.html

相关文章:

  • 重庆h5建站模板百度竞价排名查询
  • 旅游网站模板素材写软文能赚钱吗
  • 网站建设需要用什么书缅甸新闻最新消息
  • 室内设计官方网站网课培训机构排名前十
  • b2b电子商务网站盈利模式百度快照首页
  • 单位网站怎么制作深圳有实力的seo公司
  • 广而告之微信推广平台吴中seo网站优化软件
  • 周浦做网站公司常用的网站推广方法
  • 汕头市澄海建设局门户网站怎样制作一个网页
  • 焦作网站建设策划长沙网站推广公司
  • 深圳网站建设 制作元网站文章优化技巧
  • 佛山做网站多少钱搜狗seo怎么做
  • 酒店网站建设日程表seo网络推广专员
  • 北京大型网站建设移动建站模板
  • 山东省住房和建设厅网站深圳外贸seo
  • 十大网站建设公司排名如何免费注册网站
  • 全国招商代理平台网络优化这个行业怎么样
  • 企业为何要建设网站网站建设公司排行榜
  • 荥阳网站建设多少钱沈阳seo技术
  • 网站登录注册页面模板下载你对网络营销的理解
  • 网站建设虚拟服务器深圳营销型网站建设
  • 二次开发简单吗全国推广优化网站
  • 宁波网络公司在哪里百度快速收录seo工具软件
  • 嵌入式硬件开发重庆seo技术教程
  • 农业部项目建设管理网站新闻 最新消息
  • 国家城乡住房建设部网站怎么设置自己的网站
  • 东营建设局网站爱站查询工具
  • 珠海单位网站建设东莞外贸优化公司
  • 山西网站建设开发团队seo运营是做什么的
  • 网络方案seo实战优化