我正在使用Java Spring框架和JWT - Java Web Tokens。我有低于类
import java.util.function.Function;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import app.com.javainuse.config.JwtTokenUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class Test {
public static void main(String[] args) {
User u=new User("javainuse", "$2a$10$slYQmyNdGzTn7ZLBXBChFOC9f6kFjAqPhccnP6DxlWXx2lPk1C3G6",new ArrayList<>());
UserDetails ud=u;
JwtTokenUtil jwtTokenUtil=new JwtTokenUtil();
String token = jwtTokenUtil.generateToken(ud);
Test t=new Test();
System.out.println(t.getClaimFromToken(token, Claims::getSubject));
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
System.out.println(claims.toString());
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser().setSigningKey("javainuse").parseClaimsJws(token).getBody();
}
}
字符串
我无法理解main方法中包含Claims::getSubject的语句。它被传递到一个函数接口,名为Function<Claims,T> claimresolver。一个没有实现的方法如何引用getSubject,并从getClaimFromToken方法中的claims对象返回subject?当我们把方法引用传递给函数接口时,我们的方法必须有体重吗?但是Claims是一个接口,getSubject没有主体,那么“claimsResolver.apply(claims);“能得到主题值吗?
3条答案
按热度按时间f87krz0w1#
这里的
Claims::getSubject
语法是向Function
接口传递一个方法引用,而不是实现完整的lambda表达式。其工作原理的关键在于,
Claims
是一个接口,它扩展了io.jsonwebtoken
库中的Claims
接口。io.jsonwebtoken.Claims
接口定义了各种getter方法,如getSubject()
,getIssuer()
等。而不提供实现。所以当我们调用:
字符串
我们提供了
io.jsonwebtoken.Claims
接口上getSubject()
方法的参考。即使接口不提供实现,在运行时
claims
对象实际上是实现io.jsonwebtoken.Claims
接口并提供getSubject()
的具体实现的某个类的示例。当调用
claimsResolver.apply(claims)
时,它将调用claims
示例上的底层getSubject()
方法,该方法返回subject值。总结一下:
Claims::getSubject
提供了接口方法的参考claims
对象提供了该接口的实现claimsResolver.apply(claims)
能够调用实现的getSubject()
方法返回值h4cxqtbf2#
someInstance.getSubject()
烤了一个蛋糕并把它还给你。Claims::getSubject
是烤蛋糕的配方。一个 * 做的事情 *。另一个不做任何事情,它仅仅是描述如何做这件事-无论你把它交给谁,都可以做这件事,或不做,或做10次-或将食谱传给其他人,然后谁面临同样的选择。他们可以做任何他们喜欢的事情:
当我写下制作蛋糕的食谱时,我会提到的其中一个成分是你需要淡水。
也就是说,烤蛋糕,我需要淡水。或者是一个水龙头(可以为我制造淡水的东西)。然而,做蛋糕食谱我根本不需要淡水。我只需要告诉 * 你 *(那个会按照我的食谱烤蛋糕的人):“你需要一些淡水。你怎么做到的不是我的问题!“.
换句话说,蛋糕配方是把淡水(和其他一些东西)变成蛋糕的配方。它没有解释如何获得淡水,也没有解释制作蛋糕的食谱来包裹一瓶淡水。
同样,
Claims::getSubject
是一个配方,它解释了如何将实现Claims
的类的任何示例(即:a Claims示例)转换为String。它没有附带声明的示例,也没有解释如何创建声明的示例。它只是说:如果你有一个Claims的示例,这个食谱可以让你把Claims变成一个字符串!Claims::getSubject
说:把你的要求,叫它c
。运行c.getSubject()
。瞧,你的绳子在这儿。这里,您将这个概念(将声明转换为字符串的方法)传递给
getClaimFromToken
方法,该方法显然知道如何生成Claims的示例。这就好比我今天给你一份蛋糕食谱,你明天就拿着蛋糕出现。这意味着你设法弄到了一些淡水。我不知道怎么做,我真的不需要关心-我可以享受一些蛋糕!
注意:显然,
getClaimsFromToken
知道如何创建一个示例,从令牌实现Claims
,然后应用您的配方(即调用.getSubject()
)。但这只是“猜测”而已--API的关键在于它们承诺执行X。你不需要费心去知道它是怎么做的,你只需要费心去知道它是做什么的,也许可以确定这个库是否适合它的用途,它做的是它的文档所说的。4sup72z83#
我发现它在java中被称为什么。它被称为未绑定的非静态方法引用。这里有一个链接,解释了每个类型方法引用和我要求解释的场景。未绑定非静态方法引用