文章目录
回调函数
要搞懂什么是回调函数,怎么使用回调函数
回调函数其实也是函数(方法),就像白马王子也是王子一样。在本质上回调函数和普通的函数没有区别,同样可以被其他方法调用,也可以含有参数,可以拥有返回值。最大的不同是:回调函数并不能主动的触发的,而是根据调用者来判断我是否调用,调用哪一个方法。
或者说他们调用的时机是不同的,普通的方法是可以随时调用的。
而回调函数相比普通方法更注重时机,举个栗子,有一碗饭,你不能确定它是中午饭还是下午饭,只有你吃了的时候才能确定它是什么时候的饭。
相对于回调函数,回调函数会根据调用者传递的不同参数来确定自己要调用的方法到底是哪个。(相比普通方法,回调函数更加的灵活)。
- 普通方法使用重载的方式来拓宽灵活性,但是当我们需要执行时,需要根据不同的参数来匹配执行哪一个方法
- 回调函数调用的方法是根据调用者的条件来确定实际调用的方法,也就是说回调函数本身可能有一定的抽象性。
剖析回调函数的结构
关于回调函数由两个实体对象:
- 抽象回调接口:用于定义回调方法的抽象实现
- 回调者:调用回调函数的实体
package MessageDemo;
/**
* 抽象回调接口
*/
public interface ICallBack {
/**
* 抽象回调方法
*/
public void callback();
}
package MessageDemo;
public class Caller {
public void call(ICallBack iCallBack){
System.out.println("start");
iCallBack.callback();
System.out.println("end");
}
public static void main(String[] args) {
Caller caller = new Caller();
caller.call(new ICallBack() {
@Override
public void callback() {
System.out.println("测试回调函数");
}
});
}
}
start
测试回调函数
end
其实回调接口并不陌生,你在日常的编码中可能无形的使用过回调函数。
Thread mythread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("这也是一个回调函数");
}
});
mythread.start();
监听企微消息处理添加外部联系人/添加部门的业务
写一个稍复杂一点的Demo吧(类似于根据Kafka不同的消息类型来触发不同的回调函数)
适用场景:监听Kafka队列中的企微中的消息来处理不同的业务(列举两个业务:添加外部联系人/添加企微部门列表)
先说一下整体的结构:
- 需要根据监听到的企微消息来触发不同的业务
- 通过消息触发的
- 两个不同的业务
- 根据企微的接口文档说明匹配不同消息(注本次处理的企微消息都是文本消息)
接收Kafka监听到的企微消息并选择相应的处理
@Component
public class WorkWeixinMessageListener {
@Component
public class WorkWeixinMessageListener {
private final static Logger logger = LoggerFactory.getLogger(AddCustomerEvent.class);
@Autowired
WorkWeixinMessageConverter converter;
@Autowired
private Set<WorkWeixinMessageHandler> handlers;
@Value("${weixin.qy.customer.change.url}")
private String url;
@Value("${weixin.qy.customer.change.apiKey}")
private String apiKey;
@Value("${weixin.qy.customer.change.apiSecret}")
private String apiSecret;
@Value("${weixin.qy.customer.change.timestamp:-1}")
private Long timestamp;
@Value("${workweixin.agent.microGuider.agentId}")
private String agentId;
@Value("${weixin.qy.group}")
private String group;
@PostConstruct
public void initConsumer() {
logger.info("init handlers: {}", JSON