欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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表达式的支持,功能强大,省代码

 

相关标签: Function lambda