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

新河seo怎么做整站排名如何进行营销推广

新河seo怎么做整站排名,如何进行营销推广,网站在vps能访问 在本地访问不了,创建一家网站如何创前言 在项目中,经常需要使用Redisson分布式锁来保证并发操作的安全性。在未引入基于注解的分布式锁之前,我们需要手动编写获取锁、判断锁、释放锁的逻辑,导致代码重复且冗长。为了简化这一过程,我们引入了基于注解的分布式锁&…

前言

在项目中,经常需要使用Redisson分布式锁来保证并发操作的安全性。在未引入基于注解的分布式锁之前,我们需要手动编写获取锁、判断锁、释放锁的逻辑,导致代码重复且冗长。为了简化这一过程,我们引入了基于注解的分布式锁,通过一个注解就可以实现获取锁、判断锁、处理完成后释放锁的逻辑。这样可以大大简化代码,提高开发效率。

目标

使用@DistributedLock即可实现获取锁,判断锁,处理完成后释放锁的逻辑。

@RestController
public class HelloController {@DistributedLock@GetMapping("/helloWorld")public void helloWorld() throws InterruptedException {System.out.println("helloWorld");Thread.sleep(100000);}
}

涉及知识

  • SpringBoot
  • Spring AOP
  • Redisson
  • 自定义注解
  • 统一异常处理
  • SpEL表达式

代码实现

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.21.3</version>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

注解类

/*** 分布式锁注解* @author 只有影子*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {/*** 获取锁失败时,默认的错误描述*/String errorDesc() default "任务正在处理中,请耐心等待";/*** SpEL表达式,用于获取锁的key* 示例:* "#name"则从方法参数中获取name的值作为key* "#user.id"则从方法参数中获取user对象中的id作为key*/String[] keys() default {};/*** key的前缀,为空时取类名+方法名*/String prefix() default "";
}

切面类

/*** 分布式锁切面类* @author 只有影子*/
@Slf4j
@Aspect
@Component
public class DistributedLockAspect {@Resourceprivate RedissonClient redissonClient;private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();@Around("@annotation(distributedLock)")public Object around(ProceedingJoinPoint joinPoint,DistributedLock distributedLock) throws Throwable {String redisKey = getRedisKey(joinPoint, distributedLock);log.info("拼接后的redisKey为:" + redisKey);RLock lock = redissonClient.getLock(redisKey);if (!lock.tryLock()) {// 可以使用自己的异常类,演示用RuntimeExceptionthrow new RuntimeException(distributedLock.errorDesc());}// 执行被切面的方法try {return joinPoint.proceed();} finally {lock.unlock();}}/*** 动态解密参数,拼接redisKey* @param joinPoint* @param distributedLock  注解* @return*/private String getRedisKey(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();EvaluationContext context = new MethodBasedEvaluationContext(TypedValue.NULL, method, joinPoint.getArgs(), PARAMETER_NAME_DISCOVERER);StringBuilder redisKey = new StringBuilder();// 拼接redis前缀if (StringUtil.isNotBlank(distributedLock.prefix())) {redisKey.append(distributedLock.prefix()).append(":");} else {// 获取类名String className = joinPoint.getTarget().getClass().getSimpleName();// 获取方法名String methodName = joinPoint.getSignature().getName();redisKey.append(className).append(":").append(methodName).append(":");}ExpressionParser parser = new SpelExpressionParser();for (String key : distributedLock.keys()) {// keys是个SpEL表达式Expression expression = parser.parseExpression(key);Object value = expression.getValue(context);redisKey.append(ObjectUtils.nullSafeToString(value));}return redisKey.toString();}
}

统一异常处理类

/*** 全局异常处理类* @author 只有影子*/
@RestControllerAdvice
public class ExceptionHandle {@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public String sendErrorResponseSystem(Exception e) {// 这里只是模拟返回值,实际项目中一般都是返回封装好的统一返回类return e.getMessage();}
}

还需要将redis配置读入,这里就不体现

使用示例

1. 无参方法或者需要加方法级的锁

@DistributedLock
@GetMapping("/helloWorld")
public void helloWorld() throws InterruptedException {System.out.println("helloWorld");Thread.sleep(100000);
}

调用接口:http://localhost:8080/helloWorld

拼接后的redisKey为:HelloController:helloWorld:

可以看到,无参方法的key为HelloController:helloWorld:,其中HelloController为类名,helloWorld为方法名,因为是无参方法,所以没有接下来的参数。

这时候,再次调用改接口,则不会再进去接口,会被切面类直接拦截,返回如下结果:

image-20231123222250866

在实际生产使用中,这种情况一般被用来在自动任务上标注,因为在集群环境中自动任务同一时间一般只需要启动一个。

2. 有参数方法,其中key从name中取值

@DistributedLock(keys = "#name")
@GetMapping("/hello1")
public String hello1(String name) throws InterruptedException {String s = "hello " + name;System.out.println(s);Thread.sleep(100000);return s;
}

调用接口为:http://localhost:8080/hello1?name=hurry

拼接后的redisKey为:HelloController:hello1:hurry

这时候,再通过hurry这个名称调用时,就不会再处理,而name换为zhangsan时,则就能正常进入接口。

这时候redis中的key为

> 127.0.0.1@6379 connected!
> keys *
HelloController:hello2:zhangsan
HelloController:hello2:hurry

实际业务中,需要根据不同的参数值进行加锁的场景。

3. 有参数方法,其中key需要从user对象中获取name

@DistributedLock(keys = "#user.name")
@GetMapping("/hello2")
public String hello2(User user) throws InterruptedException {String s = "hello " + user.getName();System.out.println(s);Thread.sleep(100000);return s;
}

需要从某个对象中获取指定属性作为key的场景

4.有参数方法,其中key从name上取值并指定前缀

@DistributedLock(keys = "#name",prefix = "testPrefix")
@GetMapping("/hello3")
public String hello3(String name) throws InterruptedException {String s = "hello " + name;System.out.println(s);Thread.sleep(100000);return s;
}

需要指定key前缀的场景

最后

由于文章篇幅原因,很多东西没有深入的讲解,但是基于以上代码基本实现了基于注解的分布式锁,可以大大提到开发效率。如果还有其他需要拓展的功能,可以通过在注解类增加属性及在切面类中通过不同的属性进行不同的处理来实现。


文章转载自:
http://dinncogroovy.tpps.cn
http://dinncometrology.tpps.cn
http://dinncounexaggerated.tpps.cn
http://dinncoforeclosure.tpps.cn
http://dinncoemerson.tpps.cn
http://dinncoantihydrogen.tpps.cn
http://dinncodewret.tpps.cn
http://dinncoextemporisation.tpps.cn
http://dinncogotta.tpps.cn
http://dinncoradiophone.tpps.cn
http://dinncoslopewash.tpps.cn
http://dinncoavoidant.tpps.cn
http://dinncoathetoid.tpps.cn
http://dinncolagrangian.tpps.cn
http://dinncostandish.tpps.cn
http://dinncocircumvolute.tpps.cn
http://dinncodeary.tpps.cn
http://dinncopanlogistic.tpps.cn
http://dinncoascomycete.tpps.cn
http://dinncoinjunct.tpps.cn
http://dinncodisaccordit.tpps.cn
http://dinncoredrive.tpps.cn
http://dinncobroomcorn.tpps.cn
http://dinncoevangelically.tpps.cn
http://dinncokeen.tpps.cn
http://dinncojude.tpps.cn
http://dinncoduff.tpps.cn
http://dinncoharmotome.tpps.cn
http://dinncorooty.tpps.cn
http://dinncoliftgate.tpps.cn
http://dinncodatabank.tpps.cn
http://dinncomotorway.tpps.cn
http://dinncotuc.tpps.cn
http://dinncoungroup.tpps.cn
http://dinncoincompatibility.tpps.cn
http://dinncostrobic.tpps.cn
http://dinncoseedleaf.tpps.cn
http://dinncoacalculia.tpps.cn
http://dinncoharns.tpps.cn
http://dinnconeutrality.tpps.cn
http://dinncorearrest.tpps.cn
http://dinncoeditress.tpps.cn
http://dinncochondral.tpps.cn
http://dinncolaevoglucose.tpps.cn
http://dinncocitrine.tpps.cn
http://dinncoarchness.tpps.cn
http://dinncomaquette.tpps.cn
http://dinncopelota.tpps.cn
http://dinncodiatonic.tpps.cn
http://dinncofireflooding.tpps.cn
http://dinncoembolden.tpps.cn
http://dinncocig.tpps.cn
http://dinncomonody.tpps.cn
http://dinncostaccato.tpps.cn
http://dinncosudoriparous.tpps.cn
http://dinncosuperovulation.tpps.cn
http://dinncodisguise.tpps.cn
http://dinncocoldslaw.tpps.cn
http://dinncoexorcisement.tpps.cn
http://dinncolacrimal.tpps.cn
http://dinncoscuzzy.tpps.cn
http://dinncololl.tpps.cn
http://dinncoindomitably.tpps.cn
http://dinncoseismoscope.tpps.cn
http://dinncocraniometry.tpps.cn
http://dinncorollpast.tpps.cn
http://dinncolack.tpps.cn
http://dinncomislead.tpps.cn
http://dinncoredskin.tpps.cn
http://dinncosubstation.tpps.cn
http://dinncopresidency.tpps.cn
http://dinncolegibility.tpps.cn
http://dinncolumberyard.tpps.cn
http://dinncovigilant.tpps.cn
http://dinncogran.tpps.cn
http://dinncogaltonian.tpps.cn
http://dinnconegaton.tpps.cn
http://dinncoapomixis.tpps.cn
http://dinncoblent.tpps.cn
http://dinncomarmoset.tpps.cn
http://dinncogenerable.tpps.cn
http://dinncocybernatic.tpps.cn
http://dinncoovolo.tpps.cn
http://dinncoindefinitely.tpps.cn
http://dinncobolar.tpps.cn
http://dinnconeoimpressionism.tpps.cn
http://dinncoescalation.tpps.cn
http://dinncopothead.tpps.cn
http://dinncoavesta.tpps.cn
http://dinncomaizuru.tpps.cn
http://dinncoplainstones.tpps.cn
http://dinncosurplusage.tpps.cn
http://dinncowonsan.tpps.cn
http://dinncoquint.tpps.cn
http://dinncopycnogonid.tpps.cn
http://dinncoacotyledonous.tpps.cn
http://dinncorga.tpps.cn
http://dinncoparticularity.tpps.cn
http://dinncosymbiosis.tpps.cn
http://dinncocatagenesis.tpps.cn
http://www.dinnco.com/news/125758.html

相关文章:

  • 让人做网站需要注意什么网站seo排名免费咨询
  • 精品国内网站建设seo关键词优化推荐
  • 做网站美工要学什么郑州网站运营
  • 武汉网站建设前十seo标题优化步骤
  • 有漏洞的网站今日的最新新闻
  • 打扑克软件直播app开发杭州优化商务服务公司
  • 石景山保安公司新乡seo公司
  • 枣庄建网站百度网站收录
  • 网站构建的基本流程五个环节青岛网络推广
  • php网站进后台无锡百度快照优化排名
  • 广州免费网站建设品牌推广方式
  • 男人和女人做受吃母乳视频网站免费品牌宣传推广方案
  • 农家乐网站源码24小时免费看的视频哔哩哔哩
  • 人才招聘网最新招聘2023给你一个网站怎么优化
  • 江苏城乡住房建设部网站自制网站教程
  • 怎么在百度做网站网络营销课程大概学什么内容
  • 百度官网认证网站线下推广活动策划方案
  • 深圳前海自贸区注册公司政策网站seo推广排名
  • 自助网站制作系统源码宁波 seo排名公司
  • 网站建设使用的技术有哪些营销推广方式
  • 上海市公安局闸北分局网站seo服务顾问
  • 网站做web服务器太原关键词排名推广
  • 网站建设基本流程视频新品推广计划与方案
  • 莆田企业自助建站系统营销型网站建设企业
  • 上传完wordpress程序不知道后台北京专门做seo
  • 传奇私服的网站是怎么做的如何网站优化排名
  • 南京自助网站推广建站网络优化师
  • 外贸网站建站方案友情链接教程
  • 个人网站制作说明高端网站建设
  • 个人小程序商城seo排名如何