java 8 Function特性也出现了很久了,在项目用的越来越多,记录一下个人的感悟
1 函数式参数的编程思想,对callback功能的全面替代
这个很容易理解,callback本身就是接近函数式参数的一个概念,代码封装中常会对同一个方法中相同的部分抽取,不同的部分定义成callback,调用者提供具体的实现,使用过的类HibernateDaoSupport是一个很好的体现,使用Function,Consumer可以做完美的替代,下面是我们针对幂等操作(分布式锁提供锁支持)的一个封装
/**
* 分布式锁支持,获取不到锁抛出IdempotentException
* @param lockSuffix 锁前缀
* @param paramSupplier 提供的参数bean
* @param actionFunction 处理参数的函数
* @param <T> 入参泛型
* @param <R> 返回值泛型
* @return
* @throws IdempotentException
*/
public <T,R> R idempotentAction(String lockSuffix, Supplier<T> paramSupplier, Function<T, R> actionFunction)
throws IdempotentException {
//加锁操作
ZkMutex zkMutex = zkMutexClient.getDistributedLock(lockSuffix);
logger.info("开始尝试获取锁!");
boolean getLock = zkMutex != null ? zkMutex.acquire(5, TimeUnit.SECONDS, 3) : false;
logger.info("获取锁结束!获取结果:{}", getLock);
try {
if (!getLock) {//未获取到锁
logger.info("获取锁失败!稍后重试!");
throw new IdempotentException("获取锁失败,稍后重试");
}
//逻辑块
return actionFunction.apply(paramSupplier.get());
} finally {
if (getLock && zkMutex != null) {
zkMutex.release();
logger.info("zk分布式释放锁");
}
}
}
ps: ZkMutex是继承自curator框架的InterProcessMutex类,提供了异常的屏蔽
/**
* zk锁,提供一层封装,保证zk锁在任何异常情况下不影响正常程序执行
* Created by mxl on 2017/5/22.
*/
public class ZkMutex extends InterProcessMutex {
private Logger logger = LoggerFactory.getLogger(ZkMutex.class);
private CuratorFramework client;
private String path;
public ZkMutex(CuratorFramework client, String path) {
super(client, path);
this.client = client;
this.path = path;
}
@Override
public void acquire() throws Exception {
try {
super.acquire();
} catch (Exception e) {
logger.error("获取锁失败!", e);
}
}
@Override
public boolean acquire(long time, TimeUnit unit) {
try {
return super.acquire(time, unit);
} catch (Exception e) {
logger.error("获取zk锁异常!", e);
}
return false;
}
/**
* 获取锁,支持重试
* @param time
* @param unit
* @param tries
* @return
*/
public boolean acquire(long time, TimeUnit unit, int tries) {
for (int i = 0; i < tries; i++) {
try {
if (super.acquire(time, unit)) {
return true;
}
} catch (Exception e) {
logger.error("获取锁失败,重试次数:" + tries);
}
}
return false;
}
@Override
public void release() {
try {
super.release();
deleteNode();
} catch (Exception e) {
logger.error("释放zk锁异常!", e);
}
}
/**
* 删除锁对于的节点
*/
public void deleteNode() {
try {
List<String> children = this.client.getChildren().forPath(path);
if (children == null || children.size() == 0) {
this.client.delete().forPath(path);
}
} catch (Exception e) {
logger.error("删除节点失败!", e);
}
}
}
2 泛型封装对泛型对象的实例化
/**
* 参数转换
* @param inputParam
* @param outputParam
* @param <T>
* @param <R>
* @return
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private <T, R> R convertParam (Supplier<T> inputParam, Supplier<R> outputParam) throws IllegalAccessException,
InvocationTargetException{
T t = inputParam.get();
R r = outputParam.get();
if (t != null && r != null) {
BeanUtils.copyProperties(r, t);
}
return r;
}
3 最常用的就是集合转换成stream对各种lambda表达式的支持,功能强大,省代码