回调函数:就是客户程序C调用服务程序S中的某个方法a,然后S又在某个时候反过来调用C中的某个方法b,对于C来说,这个b便叫做回调函数。
例子说明,比如封装jedis的时候,一共有几十个操作方法,每个都去获取资源、释放资源。而获取资源和释放资源的代码部分是重复的,只有实际的操作redis部分不重复。
没使用回调函数的话是这样:
package com.sid.util.callback;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @program: springboot
* @description: 不使用回调函数
* @author: Sid
* @date: 2018-11-20 09:24
* @since: 1.0
**/
public class JedisUtil {
private static JedisPool pool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 设置最大10个连接
jedisPoolConfig.setMaxTotal(10);
pool = new JedisPool(jedisPoolConfig, "localhost");
}
public String get(String key){
Jedis jedis = null;
try{
jedis = pool.getResource();
return jedis.get(key);
}finally{
if(null != jedis)
jedis.close(); // 释放资源还给连接池
}
}
public String set(String key,String value){
Jedis jedis = null;
try{
jedis = pool.getResource();
return jedis.set(key, value);
}finally{
if(null != jedis)
jedis.close(); // 释放资源还给连接池
}
}
}
有几十个操作redis的命令就要重复几十遍这部分代码:
public String get(String key){ Jedis jedis = null; try{ jedis = pool.getResource(); //doRedis }finally{ if(null != jedis) jedis.close(); } }
而使用回调函数的话, 获取和释放资源部分的代码只需要写一次,在其中去回调真正的doRedis操作,而doRedis的操作逻辑中不用关心获取、释放资源的内容。类似做了一个切面。
示例:
1.定义回调接口
package com.sid.util.callback;
import redis.clients.jedis.Jedis;
public interface RedisCallBack<T> {
T doInRedis(Jedis jedis);
}
2.分离出获取、释放资源的部分,具体业务逻辑部分使用回调函数
package com.sid.util.callback;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @program: springboot
* @description:
* @author: Sid
* @date: 2018-11-20 09:41
* @since: 1.0
**/
public class JedisOperations {
private static JedisPool pool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
pool = new JedisPool(jedisPoolConfig, "localhost");
}
<T> T execute(RedisCallBack<T> callback) {
Jedis jedis = null;
try{
jedis = pool.getResource();
return callback.doInRedis(jedis);
}finally{
if(null != jedis)
jedis.close();
}
}
}
3.具体业务部分,实现回调函数
调用execute方法可以用继承实现,也可以用依赖实现(持有JedisOperations的引用)。
package com.sid.util.callback;
import redis.clients.jedis.Jedis;
/**
* @program: springboot
* @description:
* @author: Sid
* @date: 2018-11-20 09:41
* @since: 1.0
**/
public class JedisUtilWithCallBack extends JedisOperations{
//这里可以继承JedisOperations,就能使用它的execute方法
//也能用依赖的方式,持有JedisOperations的引用然后使用它的execute方法
//JedisOperations jedisOperations = new JedisOperations();
public String get(String key){
return execute(new RedisCallBack<String>() {
@Override
public String doInRedis(Jedis jedis) {
return jedis.get(key);
}
});
}
public String set(String key,String value){
return execute(new RedisCallBack<String>() {
@Override
public String doInRedis(Jedis jedis) {
return jedis.set(key,value);
}
});
}
}