The java 8 Function feature has also appeared for a long time, and it is used more and more in the project. Let me record my personal insights.
1 The programming idea of functional parameters, a comprehensive replacement for the callback function
This is easy to understand. Callback itself is a concept close to functional parameters. In code encapsulation, the same part of the same method is often extracted, and different parts are defined as callback. The caller provides a specific implementation. The used class HibernateDaoSupport is A good embodiment, using Function, Consumer can be a perfect replacement, the following is a package for idempotent operations (distributed locks provide lock support)
/** * Distributed lock support, throw IdempotentException if the lock is not obtained * @param lockSuffix lock prefix * @param paramSupplier provided parameter bean * @param actionFunction the function to handle the parameter * @param <T> parameter generic * @param <R> return value generic * @return * @throws IdempotentException */ public <T,R> R idempotentAction(String lockSuffix, Supplier<T> paramSupplier, Function<T, R> actionFunction) throws IdempotentException { // lock operation ZkMutex zkMutex = zkMutexClient.getDistributedLock(lockSuffix); logger.info("Start trying to acquire lock!"); boolean getLock = zkMutex != null ? zkMutex.acquire(5, TimeUnit.SECONDS, 3) : false; logger.info("End of lock acquisition! Acquisition result:{}", getLock); try { if (!getLock) {//The lock is not acquired logger.info("Failed to acquire lock! Try again later!"); throw new IdempotentException("Failed to acquire lock, try again later"); } // logic block return actionFunction.apply(paramSupplier.get()); } finally { if (getLock && zkMutex != null) { zkMutex.release(); logger.info("zk distributed release lock"); } } }
ps: ZkMutex is the InterProcessMutex class inherited from the curator framework , which provides exception shielding
/** * zk lock, providing a layer of encapsulation to ensure that zk lock does not affect normal program execution in any abnormal situation * 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("Failed to acquire lock!", e); } } @Override public boolean acquire(long time, TimeUnit unit) { try { return super.acquire(time, unit); } catch (Exception e) { logger.error("Get zk lock exception!", e); } return false; } /** * Get lock, support retry * @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("Failed to acquire lock, retries: " + tries); } } return false; } @Override public void release() { try { super.release(); deleteNode(); } catch (Exception e) { logger.error("release zk lock exception!", e); } } /** * Remove the node for the lock */ 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("Failed to delete node!", e); } } }
2 Generics encapsulates the instantiation of generic objects
/** * parameter conversion * @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 The most commonly used is the support of converting sets into streams for various lambda expressions, which is powerful and saves code