`

Function 对代码封装带来的改变

阅读更多

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics