spring 接口方法引用功能接口

ssm49v7z  于 2023-08-02  发布在  Spring
关注(0)|答案(3)|浏览(90)

我正在使用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);“能得到主题值吗?

f87krz0w

f87krz0w1#

这里的Claims::getSubject语法是向Function接口传递一个方法引用,而不是实现完整的lambda表达式。
其工作原理的关键在于,Claims是一个接口,它扩展了io.jsonwebtoken库中的Claims接口。
io.jsonwebtoken.Claims接口定义了各种getter方法,如getSubject()getIssuer()等。而不提供实现。
所以当我们调用:

Claims::getSubject

字符串
我们提供了io.jsonwebtoken.Claims接口上getSubject()方法的参考。
即使接口不提供实现,在运行时claims对象实际上是实现io.jsonwebtoken.Claims接口并提供getSubject()的具体实现的某个类的示例。
当调用claimsResolver.apply(claims)时,它将调用claims示例上的底层getSubject()方法,该方法返回subject值。
总结一下:

  • Claims::getSubject提供了接口方法的参考
  • claims对象提供了该接口的实现
  • 因此,claimsResolver.apply(claims)能够调用实现的getSubject()方法返回值
h4cxqtbf

h4cxqtbf2#

someInstance.getSubject()烤了一个蛋糕并把它还给你。
Claims::getSubject是烤蛋糕的配方。
一个 * 做的事情 *。另一个不做任何事情,它仅仅是描述如何做这件事-无论你把它交给谁,都可以做这件事,或不做,或做10次-或将食谱传给其他人,然后谁面临同样的选择。他们可以做任何他们喜欢的事情:

  • 把食谱扔进垃圾桶(蛋糕就不存在了)。
  • 烤个蛋糕。
  • 烤一万块蛋糕。
  • 开始100个线程和烤100个蛋糕同时。
  • 把食谱留到以后,明天烤一些蛋糕。

当我写下制作蛋糕的食谱时,我会提到的其中一个成分是你需要淡水。
也就是说,烤蛋糕,我需要淡水。或者是一个水龙头(可以为我制造淡水的东西)。然而,做蛋糕食谱我根本不需要淡水。我只需要告诉 * 你 *(那个会按照我的食谱烤蛋糕的人):“你需要一些淡水。你怎么做到的不是我的问题!“.
换句话说,蛋糕配方是把淡水(和其他一些东西)变成蛋糕的配方。它没有解释如何获得淡水,也没有解释制作蛋糕的食谱来包裹一瓶淡水。
同样,Claims::getSubject是一个配方,它解释了如何将实现Claims的类的任何示例(即:a Claims示例)转换为String。它没有附带声明的示例,也没有解释如何创建声明的示例。它只是说:如果你有一个Claims的示例,这个食谱可以让你把Claims变成一个字符串!
Claims::getSubject说:把你的要求,叫它c。运行c.getSubject()。瞧,你的绳子在这儿。
这里,您将这个概念(将声明转换为字符串的方法)传递给getClaimFromToken方法,该方法显然知道如何生成Claims的示例。
这就好比我今天给你一份蛋糕食谱,你明天就拿着蛋糕出现。这意味着你设法弄到了一些淡水。我不知道怎么做,我真的不需要关心-我可以享受一些蛋糕!
注意:显然,getClaimsFromToken知道如何创建一个示例,从令牌实现Claims,然后应用您的配方(即调用.getSubject())。但这只是“猜测”而已--API的关键在于它们承诺执行X。你不需要费心去知道它是怎么做的,你只需要费心去知道它是做什么的,也许可以确定这个库是否适合它的用途,它做的是它的文档所说的。

4sup72z8

4sup72z83#

我发现它在java中被称为什么。它被称为未绑定的非静态方法引用。这里有一个链接,解释了每个类型方法引用和我要求解释的场景。未绑定非静态方法引用

相关问题