package com.dobbinsoft.fw.launcher.exception; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Configuration @Component public class OtherExceptionTransferHolder { /** * 初始值,与缓存 * 异常子类,第一次会 O(n) 去遍历Map Value Set */ private Map otherExceptionHandlerHolderMap; @Bean public Map otherExceptionHandlerHolderMap(List otherExceptionTransferList) { Map map = otherExceptionTransferList.stream().collect(Collectors.toMap(OtherExceptionTransfer::getExceptionClass, v -> v)); Map targetMap = new HashMap<>(); targetMap.putAll(map); this.otherExceptionHandlerHolderMap = targetMap; return targetMap; } public OtherExceptionTransfer getByClass(Class clazz) { OtherExceptionTransfer otherExceptionTransfer = otherExceptionHandlerHolderMap.get(clazz); if (otherExceptionTransfer == null) { // 循环遍历,判断class是否是处理器的子类 for (OtherExceptionTransfer transfer : otherExceptionHandlerHolderMap.values()) { // 若clazz 是 transfer class的子类,则直接用这个,并加入缓存 if (transfer.getExceptionClass().isAssignableFrom(clazz)) { return putTransfer(clazz, transfer); } } // 使用默认转换器 return putTransfer(clazz, otherExceptionHandlerHolderMap.get(Exception.class)); } return otherExceptionTransfer; } private OtherExceptionTransfer putTransfer(Class clazz, OtherExceptionTransfer transfer) { // 此处加入缓存可能是有多个线程进入。因为添加缓存属于低频操作,用Concurrent有点亏,所以这里加一把锁 synchronized (this) { // Double Check, 防止另外一个线程已经把此值设置好。 if (!otherExceptionHandlerHolderMap.containsKey(transfer.getExceptionClass())) { otherExceptionHandlerHolderMap.put(clazz, transfer); } return transfer; } } }