redis流水号工具类

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import com.va.mapper.common.ApplicationContextRegister;

public class OrderNumUtil {

	private static StringRedisTemplate stringRedisTemplate;

	/**
	 * 根据系统毫秒时间生成排序字段, 适用于服务启动中使用
	 */
	public static BigDecimal getOrderNumByCurrentTimeMillis(Environment environment) {
		EnvConfig.setEnvironment(environment);
		return getOrderNumByCurrentTimeMillis();
	}
	
	/**
	 * 根据系统毫秒时间生成排序字段, 适用于服务完全启动后使用<br>
	 * 
	 * 按毫秒内100000条记录的极限可能,公元2286年前流水号总长度不会超过19位,固定6位小数。
	 */
	public static BigDecimal getOrderNumByCurrentTimeMillis() {
		long currentTime = System.currentTimeMillis();
		long orderNum = getOrderNum("" + currentTime, TimeUnit.MILLISECONDS);
		return new BigDecimal(currentTime + orderNum / 1000000.0);
	}

	/**
	 * 利用Redis获得分布式系统下自增流水号(多台物理机要以其中某一台物理机为标准做时间同步)
	 * 
	 * @param key   <br>
	 *   关键字: 考虑到Redis可靠性因素,不建议使用常量值做为key去获得从0到无限的流水号。 <br>
	 *   关键字: 建议key结合天、小时、分、秒、毫秒等时间单位为关键值, 不建议比天还大的时间单位。
	 * 
	 * @param expireTimeUnit 过期时间单位,配合Key中的时间单位做过期设置。
	 */
	public static long getOrderNum(String key, TimeUnit expireTimeUnit) {
		if (!EnvConfig.getRedisEnable()) {
			return 0;
		}

		try {
			if (stringRedisTemplate == null) {
				stringRedisTemplate = ApplicationContextRegister.getBean(StringRedisTemplate.class);
			}

			if (stringRedisTemplate == null) {
				return 0;
			}

			RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, stringRedisTemplate.getConnectionFactory());
			long increment = entityIdCounter.getAndIncrement();

			// 过期时间
			if (increment == 0) {
				entityIdCounter.expire(1, expireTimeUnit);
			}

			return increment;
		} catch (Exception e) {
			return 0;
		}
	}

}

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware {

	private static ApplicationContext APPLICATION_CONTEXT;

	/**
	 * 设置spring上下文
	 * 
	 * @param applicationContext spring上下文
	 * @throws BeansException
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		APPLICATION_CONTEXT = applicationContext;
	}

	/**
	 * 获取容器
	 * 
	 * @return
	 */
	public static ApplicationContext getApplicationContext() {
		return APPLICATION_CONTEXT;
	}

	/**
	 * 获取容器对象
	 * 
	 * @param type
	 * @param <T>
	 * @return
	 */
	public static <T> T getBean(Class<T> type) {
		try {
			return APPLICATION_CONTEXT.getBean(type);
		} catch (Exception e) {
			return null;
		}
	}

	public static Object getBean(String beanName) {
		try {
			return APPLICATION_CONTEXT.getBean(beanName);
		} catch (Exception e) {
			return null;
		}
	}

	public static <T> T getBean(String beanName, Class<T> clazz) {
		try {
			return APPLICATION_CONTEXT.getBean(beanName, clazz);
		} catch (Exception e) {
			return null;
		}
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值