一、关于@Component
首先我们要知道,什么是Bean呢?
Springboot ApplicationContext 是Springboot保存对象实例的地方,spring已确定将这些实例将被自动管理和分发。这些实例就叫做Bean。
@Component是一个注解,它允许spring自动检测和定义Bean。
即,无需编写任何明确的代码,Spring 就能做到:
- 扫描应用,查找注解为
@Component
的类 - 将它们实例化,并注入任何指定的依赖
- 在需要的地方注入
Spring 提供了一些专门的元注解:@Controller
、@Service
和 @Repository
。它们都提供了与 @Component
相同的功能。
它们的作用都是一样的,因为它们都是由 @Component
作为元注解组成的注解。它们就像 @Component
别名,在 Spring 自动检测或依赖注入之外有专门的用途和意义。
由于 @Component
和 @Bean
之间的差异,应该注意一些重要的影响。
@Component
是一个类级别的注解,而@Bean
是方法级别的注解,因此只有在类的源代码可编辑时,才可以使用@Component
作为选项。@Bean
始终可以使用,但它的语法更加冗长。@Component
与 Spring 的自动检测兼容,但@Bean
需要手动实例化类。- 使用
@Bean
可以将 Bean 的实例化与其类定义分离。因此,可以使用它将第三方类转化为 Spring Bean。这也意味着可以添加逻辑来决定要使用哪个实例作为 Bean。
内容来自: Spring 中的 @Component 注解 - spring 中文网 (springdoc.cn)
二、token
首先,token是什么意思呢?
在计算机术语中,它是“令牌”的意思。在计算机身份认证中,token通常指服务器端生成的一串字符串,用作客户端进行请求的一个令牌。用户首次登录后,服务器会生成一个token并将其返回给客户端。之后,客户端只需要使用这个token进行请求而无需再次提供用户名和密码,简化了身份验证过程。
其次,tokenPrefix又是什么意思呢?(一般是自定义)
tokenPrefix通常指的是用于生成token(令牌)时的一个统一前缀或者标识符。这个前缀用于标识token的类型、来源或用途,以便在后续的验证或处理过程中能够正确区分和识别不同的token。
主要作用有:
-
区分不同来源的token:在一个系统中,可能存在多种不同类型的token,比如用于用户身份验证的token、用于API调用的token等。通过为不同类型的token设置不同的前缀,可以很容易地区分它们。
-
增强安全性:通过在token中添加一个难以预测和伪造的前缀,可以增加token的复杂性和难以破解性,从而增强系统的安全性。
-
简化处理逻辑:在验证或处理token时,通过检查前缀可以快速确定token的类型和相应的处理逻辑,从而简化处理过程
举个例子:TOKEN的创建,验证和更新 。
创建TOKEN:
public static String createToken(String sub){
return tokenPrefix + JWT.create()
.withSubject(sub)
.withExpiresAt(new Date(System.currentTimeMillis() + expireTime))
.sign(Algorithm.HMAC512(secret));
}
-
方法定义:
public static String createToken(String sub)
是一个公共静态方法,它接收一个字符串参数sub
并返回一个字符串。这个字符串预期是一个JWT令牌。 -
JWT类:代码中存在一个名为
JWT
的类,它有一个静态方法create()
,用于开始构建一个JWT。(这是我自己创建的类) -
设置主题:
.withSubject(sub)
是JWT
类的某个方法,用于设置JWT的主题(subject),即sub
参数的值。在JWT中,主题通常用于标识令牌的接收者,比如用户的ID。 -
设置过期时间:
.withExpiresAt(new Date(System.currentTimeMillis() + expireTime))
-
签名JWT:
.sign(Algorithm.HMAC512(secret))
-
返回令牌
验证TOKEN:
public static String validateToken(String token){
try {
return JWT.require(Algorithm.HMAC512(secret))
.build()
.verify(token.replace(tokenPrefix, ""))
.getSubject();
} catch (TokenExpiredException e){
throw new CustomException(401, "token已经过期");
} catch (Exception e){
throw new CustomException(401, "token验证失败");
}
}
更新TOKEN:
public static boolean isNeedUpdate(String token){
//获取token过期时间
Date expiresAt = null;
try {
expiresAt = JWT.require(Algorithm.HMAC512(secret))
.build()
.verify(token.replace(tokenPrefix, ""))
.getExpiresAt();
} catch (TokenExpiredException e){
return true;
} catch (Exception e){
throw new CustomException(401, "token验证失败");
}
//如果剩余过期时间少于过期时常的一般时 需要更新
return (expiresAt.getTime() - System.currentTimeMillis()) < (expireTime>>1);
}