import javax.annotation.Nonnull;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(@Nonnull ApplicationContext ctx) {
applicationContext = ctx;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
@Slf4j
@Component
@Validated
public class JdbcTemplateHolder {
private static final Map<String, NamedParameterJdbcOperations> HOLDER = new ConcurrentHashMap<>(20);
private static final ThreadLocal<String> LOCAL_ROUTE_KEY = ThreadLocal.withInitial(String::new);
public void register(
@NotBlank(message = "illegal key") String key,
@NotNull(message = "illegal dataSource") DataSource dataSource) {
HOLDER.put(key, new NamedParameterJdbcTemplate(dataSource));
}
public NamedParameterJdbcOperations get() {
String routeKey = Variables.requireNotBlank(LOCAL_ROUTE_KEY.get(), " can not find local jdbcTemplate key");
return Objects.requireNonNull(HOLDER.get(routeKey), " jdbcTemplate is null, please check ");
}
public static void assign(@NotBlank(message = "illegal jdbcTemplate key") String key) { LOCAL_ROUTE_KEY.set(key); }
public static void removeKey() { LOCAL_ROUTE_KEY.remove();}
public Map<String, NamedParameterJdbcOperations> getHolder() {
return HOLDER;
}
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class JdbcRouters {
public static void doRoute(String jdbcTemplateKey) {
JdbcTemplateHolder.assign(jdbcTemplateKey);
}
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Spliterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class StreamForks<T> {
private final Stream<T> stream;
private final Map<Object, Function<Stream<T>, ?>> forks = new HashMap<>(16);
public StreamForks(Stream<T> stream) {
this.stream = stream;
}
public static <T> StreamForks<T> of(Collection<T> collection) {
return new StreamForks<>(collection.stream());
}
public static <T> StreamForks<T> of(T[] array) {
return new StreamForks<>(Stream.of(array));
}
public StreamForks<T> fork(Object key, Function<Stream<T>, ?> fn) {
forks.put(key, fn);
return this;
}
public ForkResult done() {
ForkingStreamConsumer<T> consumer = build();
try {
stream.sequential().forEach(consumer);
} finally {
consumer.finish();
}
return consumer;
}
private ForkingStreamConsumer<T> build() {
List<BlockingQueue<T>> queues = new ArrayList<>(10);
Map<Object, Future<?>> actions = forks.entrySet().stream().reduce(new HashMap<>(16), (map, e) -> {
map.put(e.getKey(), getForkResult(queues, e.getValue()));
return map;
}, (m1, m2) -> {
m1.putAll(m2);
return m1;
});
return new ForkingStreamConsumer<>(queues, actions);
}
private Future<?> getForkResult(List<BlockingQueue<T>> queues, Function<Stream<T>, ?> fn) {
BlockingQueue<T> queue = new LinkedBlockingQueue<>();
queues.add(queue);
Spliterator<T> spliterator = new BlockingQueueSpliterator<>(queue);
Stream<T> source = StreamSupport.stream(spliterator, false);
return CompletableFuture.supplyAsync(() -> fn.apply(source));
}
public interface ForkResult {
<R> R get(Object key);
}
@SuppressWarnings("unchecked")
public static class ForkingStreamConsumer<T> implements Consumer<T>, ForkResult {
static final Object END_OF_STREAM = new Object();
private final List<BlockingQueue<T>> queues;
private final Map<Object, Future<?>> actions;
public ForkingStreamConsumer(List<BlockingQueue<T>> queues, Map<Object, Future<?>> actions) {
this.queues = queues;
this.actions = actions;
}
void finish() {
accept((T) END_OF_STREAM);
}
@Override
public <R> R get(Object key) {
try {
return ((Future<R>) actions.get(key)).get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
@Override
public void accept(T t) {
queues.forEach(q -> q.add(t));
}
}
public static class BlockingQueueSpliterator<T> implements Spliterator<T> {
private final BlockingQueue<T> queue;
public BlockingQueueSpliterator(BlockingQueue<T> queue) {
this.queue = queue;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
T t;
while (true) {
try {
t = queue.take();
break;
} catch (InterruptedException exception) {
throw new RuntimeException(exception);
}
}
if (t != ForkingStreamConsumer.END_OF_STREAM) {
action.accept(t);
return true;
}
return false;
}
@Override
public Spliterator<T> trySplit() {
return null;
}
@Override
public long estimateSize() {
return 0;
}
@Override
public int characteristics() {
return 0;
}
}
}
import static org.apache.commons.lang3.reflect.MethodUtils.invokeMethod;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.util.regex.Pattern;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.reflect.FieldUtils;
@UtilityClass
@SuppressWarnings("unchecked")
public class Fields {
private final Pattern GET_PATTERN = Pattern.compile("^get[A-Z].*");
private final Pattern IS_PATTERN = Pattern.compile("^is[A-Z].*");
public <T> String fieldName(Fn<T> fn) {
try {
SerializedLambda serializedLambda = (SerializedLambda) invokeMethod(fn, true, "writeReplace");
String getter = serializedLambda.getImplMethodName();
if (GET_PATTERN.matcher(getter).matches()) {
getter = getter.substring(3);
} else if (IS_PATTERN.matcher(getter).matches()) {
getter = getter.substring(2);
}
return Introspector.decapitalize(getter);
}
catch (ReflectiveOperationException exception) { throw new UnsupportedOperationException("get field name error", exception); }
}
public void write(Object object, Field field, Object value) { write(object, field.getName(), value); }
public void write(Object object, String fieldName, Object value) {
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(fieldName, object.getClass());
propertyDescriptor.getWriteMethod().invoke(object, value);
}
catch (Exception exception) {
throw new UnsupportedOperationException(
"write field fail, Class is: [" + object.getClass() + "], field named: [" + fieldName + "]", exception);
}
}
public <T> T read(Object object, Field field) {
return read(object, field.getName());
}
public <T> T read(Object object, String fieldName) {
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(fieldName, object.getClass());
return (T) propertyDescriptor.getReadMethod().invoke(object);
}
catch (Exception exception) {
throw new UnsupportedOperationException(
"read field fail, Class is: [" + object.getClass() + "], field named: [" + fieldName + "]", exception);
}
}
public <T> T readStatic(Class<?> clazz, String staticFieldName) {
try { return (T)FieldUtils.readStaticField(clazz, staticFieldName, true); }
catch (IllegalAccessException exception) {
throw new UnsupportedOperationException( "read static field fail, Class is: [" + clazz+ "], static field named: [" + staticFieldName + "]", exception);
}
}
public <T extends Number> Class<T> readPrimitiveClass(Class<T> numberClass) { return readStatic(numberClass, "TYPE"); }
@FunctionalInterface
public interface Fn<T> extends Serializable {
Object apply(T object);
}
}
import static java.util.stream.Collectors.joining;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Response handleBusinessException(BusinessException exception) {
log.error("OFF PAY BusinessException: {}", exception.getRtnMsg());
return Response.fail(exception.getRtnCode(), exception.getRtnMsg());
}
@ExceptionHandler(value = BindException.class)
public Response handleBindException(BindException exception) {
String exceptionMessage = exception.getBindingResult().getAllErrors().stream()
.map(ObjectError::getDefaultMessage).collect(joining(";"));
log.error("OFF PAY BindException: {}", exceptionMessage);
return Response.fail(exceptionMessage);
}
@ExceptionHandler(ApplicationException.class)
public Response handleApplicationException(ApplicationException exception) {
log.error("OFF PAY BusinessException: {}", exception.getMessage());
return Response.fail(exception.getCode(), exception.getMessage());
}
@ExceptionHandler(MissingServletRequestParameterException.class)
public Response handleMissingServletRequestParameterException(MissingServletRequestParameterException exception) {
log.error("OFF PAY BusinessException: {}", exception.getMessage());
return Response.fail(exception.getMessage());
}
@ExceptionHandler(ConstraintViolationException.class)
public Response handleConstraintViolationException(ConstraintViolationException exception) {
String exceptionMessage = exception.getConstraintViolations().stream().map(ConstraintViolation::getMessage)
.collect(joining(";"));
log.error("OFF PAY ConstraintViolationException: {}", exceptionMessage);
return Response.fail(exceptionMessage);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
log.error("OFF PAY MethodArgumentNotValidException: {}", exception.getMessage());
return Response.fail(exception.getBindingResult().getFieldError().getDefaultMessage());
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
log.error("OFF PAY HttpRequestMethodNotSupportedException: {}", exception.getMessage());
return Response.fail("unSupport http method");
}
@ExceptionHandler(RuntimeException.class)
public Response handleRuntimeException(RuntimeException exception) {
log.error("OFF PAY RuntimeException: {}", exception.getMessage());
return Response.fail(exception.getMessage());
}
}
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class Futures implements InitializingBean {
private static Futures self;
private final ThreadPoolTaskExecutor executor;
public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier, self.executor);
}
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return CompletableFuture.runAsync(runnable, self.executor);
}
@Override
public void afterPropertiesSet() { self = this; }
}
import java.util.function.Supplier;
import lombok.experimental.UtilityClass;
@UtilityClass
public class NullSafe {
public static <T> T nullable(Supplier<T> supplier) {
try { return supplier.get(); }
catch (NullPointerException e) { return null; }
}
public static <T> T nullDefault(Supplier<T> supplier, T defaultValue) {
try { return supplier.get(); }
catch (NullPointerException e) { return defaultValue; }
}
public static <T> T nullThrow(Supplier<T> supplier, RuntimeException exception) {
try { return supplier.get(); }
catch (NullPointerException e) { throw exception; }
}
public void nullThrow(Runnable runnable, RuntimeException exception) {
try { runnable.run(); }
catch (NullPointerException e) { throw exception; }
}
}