分布式锁的使用

1. 将加锁的方法抽离,装载加锁的方法,相关业务写在这里面,也就是需要上锁的操作,key值通过标签传入
package com.cloud.drore.eboos.common.util;


import org.springframework.boot.autoconfigure.klock.annotation.Klock;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.annotation.Resource;
import java.math.BigDecimal;
import static org.springframework.boot.autoconfigure.klock.model.LockType.Fair;


/**
 * 
 *
 * @Description: 
* @Project: eboos
* @CreateDate: Created in 2018/3/23 0023 上午 11:18
* @Author: 夏凯 */ @Component public class RedisKeysClockUtil { @Resource JedisPoll jedisPoll; /** * @param key * @param money * @param flag * @ClassName: RedisKeysClockUtil * @Return: java.math.BigDecimal * @Decription: 根据key值,金额变动值,变动类型得到变动之后的资金池金额 * @CreateDate: Created in 2018/3/23 0023 下午 2:32 * @Author: 夏凯 * @Modify: */ @Klock(keys = {"{#key}"}, lockType = Fair, waitTime = 10) //true 加 false 减 public BigDecimal cashPoolChange(String key, BigDecimal money, Boolean flag) { JedisPool jedisPool = jedisPoll.redisPoolFactory(); Jedis orderJedis = jedisPool.getResource(); String beginMoney = orderJedis.get(key).toString(); if (flag) { //退款,充值 BigDecimal endMoney = new BigDecimal(beginMoney).add(money); orderJedis.set(key, endMoney.toString()); return endMoney; } else { //下单 BigDecimal endMoney = new BigDecimal(beginMoney).subtract(money); orderJedis.set(key, endMoney.toString()); return endMoney; } } /** * @param key * @param count * @param flag * @ClassName: RedisKeysClockUtil * @Return: java.lang.Integer * @Decription: 根据key值,库存变动值,变动类型得到变动之后的库存 * @CreateDate: Created in 2018/3/23 0023 下午 2:35 * @Author: 夏凯 * @Modify: */ @Klock(keys = {"{#key}"}, lockType = Fair, waitTime = 10) public Integer stockChange(String key, Integer count, Boolean flag) { //true 加 false 减 JedisPool jedisPool = jedisPoll.redisPoolFactory(); Jedis orderJedis = jedisPool.getResource(); String beginCount = orderJedis.get(key).toString(); if (flag) { // 退订 Integer endCount = Integer.parseInt(beginCount) + count; orderJedis.set(key, endCount.toString()); return Integer.parseInt(beginCount) + count; } else { //下单 Integer endCount = Integer.parseInt(beginCount) - count; orderJedis.set(key, endCount.toString()); return endCount; } } }

2.启动项修改,由于common里面的类扫描不到,需要对几个配置属性进行启动加载

package com.cloud.drore.eboss;

import com.cloud.drore.eboos.common.util.JedisPoll;
import com.cloud.drore.eboos.common.util.RedisKeysClockUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.klock.KlockAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @Author: wcy
 * @Description:
 * @Date: Created in 2017/12/27 13:40
 * @Modified By:
 */
@MapperScan(basePackages = {"com.cloud.drore.eboss.operation.mapper"})
@SpringBootApplication
@ServletComponentScan
@EnableDiscoveryClient
@EnableFeignClients
@EnableScheduling  //下面三个启动加载项
@Import({JedisPoll.class, RedisKeysClockUtil.class, KlockAutoConfiguration.class})
public class EbossOperationApplication {

    public static void main(String[] args) {
        SpringApplication.run(EbossOperationApplication.class, args);
    }
}
3. jedispool是获取到连接池信息
package com.cloud.drore.eboos.common.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 浙江卓锐科技股份有限公司 版权所有  Copyright 2018
* * @Description: 得到redisPool
* @Project: eboos
* @CreateDate: Created in 2018/3/15 18:44
* @Author: 夏凯 */ @Configuration public class JedisPoll { @Autowired RedisProperties redisProperties; @Bean public JedisPool redisPoolFactory() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(redisProperties.getPool().getMaxIdle()); jedisPoolConfig.setMaxWaitMillis(redisProperties.getPool().getMaxWait()); JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getTimeout()); return jedisPool; } }

4.kclock自动装配

klock自动装配
package org.springframework.boot.autoconfigure.klock;

import io.netty.channel.nio.NioEventLoopGroup;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.klock.config.KlockConfig;
import org.springframework.boot.autoconfigure.klock.core.BusinessKeyProvider;
import org.springframework.boot.autoconfigure.klock.core.KlockAspectHandler;
import org.springframework.boot.autoconfigure.klock.core.LockInfoProvider;
import org.springframework.boot.autoconfigure.klock.lock.LockFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.ClassUtils;

/**
 * Created by kl on 2017/12/29.
 * Content :klock自动装配
 */
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(KlockConfig.class)
@Import({KlockAspectHandler.class})
public class KlockAutoConfiguration {

    @Autowired
    private KlockConfig klockConfig;

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean
    RedissonClient redisson() throws Exception {
        Config config = new Config();
        if(klockConfig.getClusterServer()!=null){
            config.useClusterServers().setPassword(klockConfig.getPassword())
                    .addNodeAddress(klockConfig.getClusterServer().getNodeAddresses());
        }else {
            config.useSingleServer().setAddress(klockConfig.getAddress())
                    .setDatabase(klockConfig.getDatabase())
                    .setPassword(klockConfig.getPassword());
        }
        Codec codec=(Codec) ClassUtils.forName(klockConfig.getCodec(),ClassUtils.getDefaultClassLoader()).newInstance();
        config.setCodec(codec);
        config.setEventLoopGroup(new NioEventLoopGroup());
        return Redisson.create(config);
    }

    @Bean
    public LockInfoProvider lockInfoProvider(){
        return new LockInfoProvider();
    }

    @Bean
    public BusinessKeyProvider businessKeyProvider(){
        return new BusinessKeyProvider();
    }

    @Bean
    public LockFactory lockFactory(){
        return new LockFactory();
    }
}

5.这里是测试方法,大家可以启其他服务进行测试

package com.cloud.drore.eboss.operation.controller;

import com.cloud.drore.eboos.common.base.ResultMessage;
import com.cloud.drore.eboss.operation.service.impl.DistributedLockServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 *
 *
 * @Description: 分布式锁测试接口
* @Project: eboos
* @CreateDate: Created in 2018/1/6 0006 下午 5:45
* @Author: 夏凯 */ @RestController @RequestMapping("/lock") @Api(value = "/分布式锁接口", description = "分布式锁测试接口-夏凯") public class DistributedLockTestController { @Resource DistributedLockServiceImpl distributedLockServiceImpl; @ApiOperation(value = "分布式锁测试接口)") @PostMapping(value = "/test") public ResultMessage test() { return distributedLockServiceImpl.testDistributedLock(); } }

6.然后这里给下标签的相关说明,可以在方法里面传入

package org.springframework.boot.autoconfigure.klock.annotation;

import org.springframework.boot.autoconfigure.klock.model.LockType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by kl on 2017/12/29.
 * Content :加锁注解
 */
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Klock {
    /**
     * 锁的名称
     * @return
     */
    String name() default "";
    /**
     * 锁类型,默认可重入锁
     * @return
     */
    LockType lockType() default LockType.Reentrant;
    /**
     * 尝试加锁,最多等待时间
     * @return
     */
    long waitTime() default Long.MIN_VALUE;
    /**
     *上锁以后xxx秒自动解锁
     * @return
     */
    long leaseTime() default Long.MIN_VALUE;

    /**
     * 自定义业务key
     * @return
     */
     String [] keys() default {};
}

7.输入swagger地址:http://localhost:2005/swagger-ui.html#/

8.最后一定要配置完参数才能进行操作啊!否则可能会启动报错,希望能帮到大家

9.本文地址:https://blog.csdn.net/qq_34754038/article/details/79677679

最后贴下git的地址,欢迎留言
点击打开链接







你可能感兴趣的:(redis,分布式,redis,分布式锁,swagger)