1. 知识回顾
写文章之前,还是先补充一下函数式接口的知识。什么是函数式接口(Functional Interfaces)?函数式接口是jdk8的新特性之一,函数式接口是只包含一个抽象方法声明的接口。按分类主要分为四大接口类型: Function、Consumer、Predicate、Supplier
接口  | 参数  | 返回值  | 说明  | 
  | 无  | T  | 供给型,无参,返回一个指定泛型的对象  | 
  | T  | 无  | 消费型,传入一个指定泛型的参数,无返回值  | 
  | T  | Boolean  | 断言型,判断函数,返回true或者false  | 
  | T  | R  | 方法型,输入一个参数,返回一个结果  | 
拓展如下,也可以直接去java.util.function包里面看,jdk提供了很多函数式接口
序号  | 函数式接口  | 描述说明  | 
1  |   | 代表了一个接受两个输入参数的操作,并且不返回任何结果  | 
2  |   | 代表了一个接受两个输入参数的方法,并且返回一个结果  | 
3  |   | 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果  | 
4  |   | 代表了一个两个参数的boolean值方法  | 
5  |   | 代表了boolean值结果的提供方  | 
6  |   | 代表了接受一个输入参数并且无返回的操作  | 
7  |   | 代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。  | 
8  |   | 代表一个接受double值参数的操作,并且不返回结果。  | 
9  |   | 代表接受一个double值参数的方法,并且返回结果  | 
10  |   | 代表一个拥有double值参数的boolean值方法  | 
11  |   | 代表一个double值结构的提供方  | 
12  |   | 接受一个double类型输入,返回一个int类型结果。  | 
13  |   | 接受一个double类型输入,返回一个long类型结果  | 
14  |   | 接受一个参数同为类型double,返回值类型也为double 。  | 
15  |   | 接受一个输入参数,返回一个结果。  | 
16  |   | 接受两个参数同为类型int,返回值类型也为int 。  | 
17  |   | 接受一个int类型的输入参数,无返回值 。  | 
18  |   | 接受一个int类型输入参数,返回一个结果 。  | 
19  |   | :接受一个int输入参数,返回一个布尔值的结果。  | 
20  |   | 无参数,返回一个int类型结果。  | 
21  |   | 接受一个int类型输入,返回一个double类型结果 。  | 
22  |   | 接受一个int类型输入,返回一个long类型结果。  | 
23  |   | 接受一个参数同为类型int,返回值类型也为int 。  | 
24  |   | 接受两个参数同为类型long,返回值类型也为long。  | 
25  |   | 接受一个long类型的输入参数,无返回值。  | 
26  |   | 接受一个long类型输入参数,返回一个结果。  | 
27  |   | R接受一个long输入参数,返回一个布尔值类型结果。  | 
28  |   | 无参数,返回一个结果long类型的值。  | 
29  |   | 接受一个long类型输入,返回一个double类型结果。  | 
30  |   | 接受一个long类型输入,返回一个int类型结果。  | 
31  |   | 接受一个参数同为类型long,返回值类型也为long。  | 
32  |   | 接受一个object类型和一个double类型的输入参数,无返回值。  | 
33  |   | 接受一个object类型和一个int类型的输入参数,无返回值。  | 
34  |   | 接受一个object类型和一个long类型的输入参数,无返回值。  | 
35  |   | 接受一个输入参数,返回一个布尔值结果。  | 
36  |   | 无参数,返回一个结果  | 
37  |   | 接受两个输入参数,返回一个double类型结果  | 
38  |   | 接受一个输入参数,返回一个double类型结果  | 
39  |   | 接受两个输入参数,返回一个int类型结果  | 
40  |   | 接受一个输入参数,返回一个int类型结果。  | 
41  |   | 接受两个输入参数,返回一个long类型结果。  | 
42  |   | 接受一个输入参数,返回一个long类型结果  | 
43  |   | 接受一个参数为类型T,返回值类型也为T。  | 
2. 问题描述
最近项目进行重构之后,工程安装api、service、web等进行模块划分,但是缓存用户信息的是写在一个工具类里,使用ThreadLocal进行缓存,在一个service工程里需要用到工具类,直接将工具类搬过去,显然不合适,而且如果业务分为一个独立服务之后,ThreadLocal的数据是不能被其他线程访问的,所以不合适,那么要怎么处理?
3. 解决方案
想到使用jdk8的函数式接口进行回调,在Service类的方法传一个Fucntion函数,在Controller层进行实现,Service的业务执行完成之后,在通过Function函数回调获取用户信息
public class SampleController {
@Autowired
DoService service;
public void api() {
// controller类实现Function函数方法
Function fun = userCode->UserUtils.getUser(userCode);
service.invoke(Long id , fun);
}
}
public class DoService{
public void invoke(Long id , Function<String,User> fun) {
// do something
String applyUserCode = "admin";
// 业务处理好之后,进行回调获取用户信息
User applyMan = fun.apply(applyUserCode);
}
}
                










