Function 对代码封装带来的改变
程序员文章站
2022-07-12 18:32:48
...
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表达式的支持,功能强大,省代码