有时候看源码,我们会受到一些启发。
spring-core中的AlternativeJdkIdGenerator类,一个生成UUID的类,仔细研究一下 发现他和UUID的randomUUID很相似。
public class AlternativeJdkIdGenerator implements IdGenerator {
private final Random random;
public AlternativeJdkIdGenerator() {
SecureRandom secureRandom = new SecureRandom();
byte[] seed = new byte[8];
/*生成用户指定的随机字节数*/
secureRandom.nextBytes(seed);
this.random = new Random(new BigInteger(seed).longValue());
}
@Override
public UUID generateId() {
byte[] randomBytes = new byte[16];
/*生成随机字节并将其放入用户提供的字节数组中。产生的随机字节数等于字节数组的长度。*/
this.random.nextBytes(randomBytes);
/*UUID的最高有效位*/
long mostSigBits = 0;
for (int i = 0; i < 8; i++) {
mostSigBits = (mostSigBits << 8) | (randomBytes[i] & 0xff);
}
/*UUID的最低有效位*/
long leastSigBits = 0;
for (int i = 8; i < 16; i++) {
leastSigBits = (leastSigBits << 8) | (randomBytes[i] & 0xff);
}
return new UUID(mostSigBits, leastSigBits);
}
}
下面是UUID的randomUUID方法:
public static UUID randomUUID() {
SecureRandom ng = Holder.numberGenerator;
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
其实AlternativeJdkIdGenerator就是spring自定义的UUID生成器。唯一的区别就在于UUID最高/最低有效位。