package com.yami.trading.common.util; import java.io.File; import java.io.UnsupportedEncodingException; import java.lang.management.ManagementFactory; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.websocket.DeploymentException; import javax.websocket.server.ServerContainer; import javax.websocket.server.ServerEndpointConfig; import org.slf4j.Logger; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.SpringApplication; import org.springframework.boot.origin.OriginTrackedValue; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.Ordered; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.SystemPropertyUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.support.GenericWebApplicationContext; import com.yami.trading.common.config.ThreadPool; /** * @author JORGE * @description SpringBoot应用工具 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class ApplicationUtil { /** * SpringBoot应用命令行启动参数 */ private static String[] cmdLineArgs; /** * Bean标识模式 */ public enum BeanIdMode { BEAN_NAME, BEAN_TYPE } /** * SpringBoot应用上下文环境 */ private static SpringApplication springApplication; /** * SpringBoot环境 */ private static StandardEnvironment environment; /** * SpringBoot生命周期字典 */ private static ConcurrentHashMap lifecycleDict; /** * 工程类路径配置 */ private static final String PROJECT_CLASS_PATH = "java.class.path"; /** * 八字节缓冲 */ private static final ByteBuffer EIGHT_BUFFER = ByteBuffer.allocate(8); /** * Email地址分隔符正则式 */ private static final Pattern EMAIL_SEPARATOR_REGEX = Pattern.compile("@"); /** * 路径前缀正则式(同时兼容jar[war]包和工程模式) */ private static final Pattern PATH_PREFIX = Pattern.compile("[/\\\\]{1}[A-Za-z]{1}:"); /** * WebSocket容器配置 */ private static final String WS_SERVER_CONTANER = "javax.websocket.server.ServerContainer"; /** * SpringBoot配置文件后缀键(默认支持Nacos) */ private static final String[] CONFIG_SUFFIX = { ".yml]", ".yaml]", ".properties]", "DEFAULT_GROUP" }; /** * 类路径分隔符正则式 */ private static final Pattern CLASSPATH_SEPARATOR_REGEX = Pattern.compile(File.pathSeparator); /** * Spring应用上下文字典 */ private static final LinkedHashMap, GenericApplicationContext> CONTEXT_DICT = new LinkedHashMap, GenericApplicationContext>(); /** * 获取Spring上下文字典 * * @return */ public static LinkedHashMap, GenericApplicationContext> getContextDict() { return new LinkedHashMap, GenericApplicationContext>(CONTEXT_DICT); } /** * 获取命令行参数列表 * * @return */ public static String[] getCmdLineArgs() { return cmdLineArgs; } /** * 获取Web应用服务器端口 * * @return 端口 */ public static Integer getServerPort() { return getProperty("server.port", Integer.class); } /** * 获取SpringBoot应用名 * * @return 端口 */ public static String getApplicationName() { return getProperty("spring.application.name"); } /** * 获取系统部署环境 * * @return dev/test/pre/prod..etc */ public static String getDeployEnvironment() { String[] profiles = getEnvironment().getActiveProfiles(); if (null == profiles || 0 == profiles.length) return null; return profiles[0]; } /** * 根据JVM实例时间获取UUID字串序列 * @description 不同JVM例程的随机值不同,同一个JVM例程随机值相同 * @return UUID字串序列 */ public static final String getRandomJvmTimeUUID(String... prexfixs) { EIGHT_BUFFER.clear(); EIGHT_BUFFER.putLong(System.nanoTime()); EIGHT_BUFFER.flip(); byte[] b=new byte[8]; EIGHT_BUFFER.get(b); EIGHT_BUFFER.clear(); String prefix=(null==prexfixs || 0==prexfixs.length)?"":prexfixs[0]; prefix=(null==prefix || (prefix=prefix.trim()).isEmpty())?"":prefix; return prefix+UUID.nameUUIDFromBytes(b).toString().replace("-", ""); } /** * 根据操作系统时间获取UUID字串序列 * @return UUID字串序列 */ public static final synchronized String getCurrentTimeUUID(String... prexfixs) { EIGHT_BUFFER.clear(); EIGHT_BUFFER.putLong(System.currentTimeMillis()); EIGHT_BUFFER.flip(); byte[] b=new byte[8]; EIGHT_BUFFER.get(b); EIGHT_BUFFER.clear(); String prefix=(null==prexfixs || 0==prexfixs.length)?"":prexfixs[0]; prefix=(null==prefix || (prefix=prefix.trim()).isEmpty())?"":prefix; String uuid=prefix+UUID.nameUUIDFromBytes(b).toString().replace("-", ""); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return uuid; } /** * 输出线程堆栈信息 * @param loggers */ public static void printStackTrace(Logger... loggers) { List elementList=Arrays.stream(Thread.currentThread().getStackTrace()) .map(element->new StringBuilder(element.getClassName()).append(".") .append(element.getMethodName()).append(":") .append(element.getLineNumber()).toString()) .collect(Collectors.toList()); Logger logger=(null==loggers || 0==loggers.length)?null:loggers[0]; if(null==logger) { System.out.println(String.join("\n", elementList)); }else { logger.error(String.join("\n", elementList)); } } /** * 获取Web应用上下文路径(默认空串) * * @return 上下文路径 */ public static String getContextPath() { String appName = null; StandardEnvironment environment = getEnvironment(); if (null != environment) { appName = environment.getProperty("server.servlet.contextPath"); if (null == appName || appName.trim().isEmpty()) appName = environment.getProperty("server.servlet.context-path"); if (null == appName || appName.trim().isEmpty()) appName = environment.getProperty("server.servlet.context_path"); } if (null != appName && !appName.trim().isEmpty()) return appName; GenericApplicationContext applicationContext = getApplicationContext(); if (null != applicationContext) appName = applicationContext.getApplicationName(); if (null == appName || appName.trim().isEmpty()) return ""; return appName; } /** * 获取Servlet配置 * * @return Servlet配置 */ public static ServletConfig getServletConfig() { GenericApplicationContext applicationContext = getApplicationContext(); if (null == applicationContext) return null; if (!(applicationContext instanceof GenericWebApplicationContext)) return null; return ((GenericWebApplicationContext) applicationContext).getServletConfig(); } /** * 获取Servlet上下文 * * @return Servlet上下文 */ public static ServletContext getServletContext() { GenericApplicationContext applicationContext = getApplicationContext(); if (null == applicationContext) return null; if (!(applicationContext instanceof GenericWebApplicationContext)) return null; return ((GenericWebApplicationContext) applicationContext).getServletContext(); } /** * 从当前线程中获取请求上下文属性 * * @return 请求属性对象 */ public static RequestAttributes getRequestAttributes() { RequestAttributes requestAttributes = null; try { requestAttributes = RequestContextHolder.currentRequestAttributes(); } catch (IllegalStateException e) { } return requestAttributes; } /** * 获取Servlet请求对象 * * @return Servlet请求对象 */ public static HttpServletRequest getServletRequest() { RequestAttributes requestAttributes = getRequestAttributes(); // not found in spring application context if (null == requestAttributes) return null; // not servlet context if (!(requestAttributes instanceof ServletRequestAttributes)) return null; return ((ServletRequestAttributes) requestAttributes).getRequest(); } /** * 获取Servlet响应对象 * * @return Servlet请求对象 */ public static HttpServletResponse getServletResponse() { RequestAttributes requestAttributes = getRequestAttributes(); // not found in spring application context if (null == requestAttributes) return null; // not servlet context if (!(requestAttributes instanceof ServletRequestAttributes)) return null; return ((ServletRequestAttributes) requestAttributes).getResponse(); } /** * 获取HttpSession对象 * * @return HttpSession对象 */ public static HttpSession getHttpSession(boolean... createIfNotExists) { HttpServletRequest request = getServletRequest(); return null == request ? null : request.getSession((null == createIfNotExists || 0 == createIfNotExists.length) ? true : false); } /** * 获取底层服务器实现的WebSocket容器 * * @return WebSocket容器 */ public static ServerContainer getWebSocketContainer() { ServletContext servletContext = ApplicationUtil.getServletContext(); if (null == servletContext) return null; Object object = servletContext.getAttribute(WS_SERVER_CONTANER); if (null == object || !ServerContainer.class.isInstance(object)) return null; return ServerContainer.class.cast(object); } /** * 绑定EndPoint * * @param path ForExample:"/ws/chat" * @param endpoint 继承至javax.websocket.Endpoint类的子类 * @throws DeploymentException */ public static void bindEndpoint(String path, Class endpoint) throws DeploymentException { ServerContainer container = getWebSocketContainer(); if (null == container) throw new RuntimeException("Not Found WebSocket Container"); container.addEndpoint(ServerEndpointConfig.Builder.create(endpoint, path).build()); } /** * 绑定EndPoint * * @param endpoint 使用注解ServerEndpoint(value = "/ws/chat")标注的类 * @throws DeploymentException */ public static void bindEndpoint(Class endpoint) throws DeploymentException { ServerContainer container = getWebSocketContainer(); if (null == container) throw new RuntimeException("Not Found WebSocket Container"); container.addEndpoint(endpoint); } /** * 获取应用入口参数 * @return 应用入口参数数组 * @throws DeploymentException */ public static String[] getBootAllArguments() { ApplicationArguments arguments=getBean(ApplicationArguments.class); return null==arguments?null:arguments.getSourceArgs(); } /** * 获取Redis模版 * @return Redis模版 */ public static RedisTemplate getRedisTemplate() { Map templateMap=ApplicationUtil.getBeansOfType(RedisTemplate.class); return (null==templateMap || templateMap.isEmpty())?null:templateMap.getOrDefault("redisTemplate", templateMap.values().iterator().next()); } /** * 启动重置Spring上下文监控任务 * @param listKey Redis队列键 * @param resetRunnables 重置任务 */ public static void startResetContextMonitorTask(String listKey,Class bootClass,Runnable... resetRunnables) { Runnable resetRunnable=(null==resetRunnables || 0==resetRunnables.length)?null:resetRunnables[0]; ThreadPoolTaskExecutor executor=ThreadPool.getFixedTaskExecutor(1,"REDIS-HOOK-RESET-CONTEXT"); if(null==resetRunnable) { resetRunnable=()->{ StringRedisTemplate template=ApplicationUtil.getBean(StringRedisTemplate.class); if(null==template) return; ListOperations listOperations=template.opsForList(); while(true) { if(null==listOperations.rightPop(listKey, 3L, TimeUnit.SECONDS)) continue; break; } getApplicationContext().close(); SpringApplication.run(bootClass,cmdLineArgs); }; } executor.execute(resetRunnable); } /** * 动态获取SpringBoot配置参数字典 * * @param suffixStr 配置文件后缀 * @return 配置字典 * @description SpringBoot环境配置参数必须是动态获取,不能静态初始化, * 因为在SpringCloud应用中可以通过配置管理中心动态更新环境配置参数值 */ public static ConcurrentHashMap getPropertiesConfig(String... suffixStr) { StandardEnvironment environment = getEnvironment(); ConcurrentHashMap properties = new ConcurrentHashMap(); String[] suffixStrs = (null == suffixStr || 0 == suffixStr.length) ? CONFIG_SUFFIX : suffixStr; Set configSuffixs = new HashSet(Arrays.asList(suffixStrs)); environment.getPropertySources().stream().filter(propertySource -> { for (String e : configSuffixs) if (propertySource.getName().endsWith(e)) return true; return false; }).forEach(propertySource -> { Object source = propertySource.getSource(); if (!(source instanceof Map)) return; ((Map) source).forEach((k, v) -> { Object strVal = (v instanceof String) ? (String) v : ((OriginTrackedValue) v).getValue(); if (null != strVal) strVal = resolvePlaceHolder(strVal.toString()); properties.put((String) k, strVal); }); }); return properties; } /** * 递归解析配置占位符 * * @param placeHolder 占位符 * @return 字串值 */ public static String resolvePlaceHolder(String placeHolder) { if (null == placeHolder) return null; placeHolder = placeHolder.trim(); if (placeHolder.isEmpty()) return ""; StandardEnvironment environment = getEnvironment(); if (!placeHolder.startsWith(SystemPropertyUtils.PLACEHOLDER_PREFIX) || !placeHolder.endsWith(SystemPropertyUtils.PLACEHOLDER_SUFFIX)) { return placeHolder; } String placeHolderKey = placeHolder.substring(2, placeHolder.length() - 1); String valueHolder = environment.getProperty(placeHolderKey); if (null == valueHolder || valueHolder.isEmpty()) return placeHolder; return resolvePlaceHolder(valueHolder); } public static ConcurrentHashMap getLifecycleDict() { return lifecycleDict; } /** * 获取SpringBoot原始配置环境 * * @return SpringBoot配置环境 */ public static StandardEnvironment getRawEnvironment() { return environment; } /** * 获取SpringBoot配置环境 * * @param levels 上下文层级(从0开始计算) * @return SpringBoot配置环境 */ public static StandardEnvironment getEnvironment(Integer... levels) { GenericApplicationContext applicationContext = getApplicationContext(levels); if (null == applicationContext) return environment; return (StandardEnvironment) applicationContext.getEnvironment(); } /** * 获取SpringBoot应用容器 * * @return SpringBoot应用容器 */ public static SpringApplication getSpringApplication() { return springApplication; } /** * 获取Spring之BeanFactory * * @param levels 上下文层级 * @return BeanFactory */ public static DefaultListableBeanFactory getBeanFactory(Integer... levels) { GenericApplicationContext applicationContext = getApplicationContext(levels); return null == applicationContext ? null : applicationContext.getDefaultListableBeanFactory(); } /** * 获取Spring应用上下文 * * @param levels 上下文层级(从0开始计算) * @return ApplicationContext */ public static GenericApplicationContext getApplicationContext(Integer... levels) { if (0 == CONTEXT_DICT.size()) return null; GenericApplicationContext applicationContext = null; int index = null == levels || 0 == levels.length ? CONTEXT_DICT.size() - 1 : levels[0].intValue(); Iterator, GenericApplicationContext>> contextIterator = CONTEXT_DICT.entrySet().iterator(); for (int i = 0; i <= index && contextIterator.hasNext(); applicationContext = contextIterator.next().getValue(), i++); return applicationContext; } /** * 获取操作系统属性字典 * * @return 字典类型 */ public static Map getSystemProperties() { return getEnvironment().getSystemEnvironment(); } /** * 获取虚拟机系统属性字典 * * @return 字典类型 */ public static Map getJVMProperties() { return getEnvironment().getSystemProperties(); } /** * 设置生命周期全局域缓存 * * @param key 键 * @param value 值 */ public static void setValue(String key, Object value) { lifecycleDict.put(key, value); } /** * 获取生命周期全局域缓存 * * @param key 键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static Object getValue(String key, Object... defaultValue) { return getValue(key, Object.class, defaultValue); } /** * 获取生命周期全局域缓存 * * @param key 键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getValue(String key, Class returnType, R... defaultValue) { return getValue(key, null, returnType, defaultValue); } /** * 获取生命周期全局域缓存 * * @param key 键 * @param defaultKey 默认键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getValue(String key, String defaultKey, Class returnType, R... defaultValue) { R defaultVal = (null == defaultValue || 0 == defaultValue.length) ? null : defaultValue[0]; Object value = lifecycleDict.get(key); if (null == value && null != defaultKey) value = lifecycleDict.get(defaultKey); if (null == value) return defaultVal; return returnType.cast(value); } /** * 获取Spring上下文中指定Bean名称对应的Bean对象 * * @param beanName BeanId * @return 对象类型 */ public static Object getBean(String beanName) { return (null == beanName || beanName.trim().isEmpty())?null:getBean(beanName, Object.class); } /** * 获取Spring上下文中兼容到指定类型的唯一Bean对象 * * @param beanType Bean类型 * @return 泛化类型 * @description 兼容Bean不唯一或不存在则返回null */ public static R getBean(Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); return (null == beanType || null == applicationContext)?null:applicationContext.getBean(beanType); } /** * 获取Spring上下文中给定Bean类型简单名对应的Bean对象 * * @param beanType Bean类型 * @return 泛化类型 */ public static R getBeanOfName(Class beanType) { if (null == beanType) return null; String beanName = CommonUtil.lowerFirstChar(beanType.getSimpleName()); return getBean(beanName, beanType); } /** * 获取Spring上下文中兼容到指定类型的随机Bean对象 * * @param beanType Bean类型 * @return 泛化类型 * @description 兼容Bean不存在则返回null,兼容Bean有多个则随机返回一个 */ public static R getRandomBean(Class beanType) { if (null == beanType) return null; Map beanDict = getBeansOfType(beanType, true, true); if (null == beanDict || beanDict.isEmpty()) return null; return beanDict.entrySet().iterator().next().getValue(); } /** * 获取Spring上下文中的类型兼容Bean字典 * * @param beanType Bean类型 * @return 泛化字典 */ public static Map getBeansOfType(Class beanType) { return null == beanType?null:getBeansOfType(beanType, true, true); } /** * 获取Spring上下文中的类型兼容Bean字典 * * @param beanType Bean类型 * @return 泛化字典 */ public static Map getBeansOfType(Class beanType, boolean includeNonSingletons,boolean requireInit) { GenericApplicationContext applicationContext = getApplicationContext(); return (null == beanType || null == applicationContext)?null:applicationContext.getBeansOfType(beanType, includeNonSingletons, requireInit); } /** * 获取Spring上下文中的Bean对象 * * @param beanName BeanId * @param beanType Bean类型 * @return 泛化类型 */ public static R getBean(String beanName, Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanName || null == beanType || null == applicationContext || beanName.trim().isEmpty()) return null; return !applicationContext.containsBean(beanName)?null:applicationContext.getBean(beanName, beanType); } /** * 通过BeanName和beanType在容器中搜索Bean * * @param beanName BeanId * @param beanType Bean类型 * @return 对象类型 */ public static Object getBeanOfSearch(String beanName, Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); if (null != beanName && !beanName.trim().isEmpty() && null != applicationContext) { if (applicationContext.containsBean(beanName)) { return applicationContext.getBean(beanName); } } if (null == beanType || null == applicationContext) return null; Map beanDict = applicationContext.getBeansOfType(beanType, true, true); if (null == beanDict || beanDict.isEmpty()) return null; if (beanDict.size() > 1) return beanDict; return beanDict.entrySet().iterator().next().getValue(); } /** * 获取Spring上下文中的Bean定义 * * @param beanName BeanId * @return Bean定义对象 * @description 从单例对象字典singletonObjects中获取指定Bean名称对应的单例Bean对象 */ public static Object getSingletonBean(String beanName) { if (null == beanName || beanName.trim().isEmpty()) return null; return getSingletonBean(beanName, Object.class); } /** * 获取Spring上下文中的Bean定义 * * @param beanName BeanId * @param type Bean类型 * @return 泛化类型 * @description 从单例对象字典singletonObjects中获取指定Bean名称对应的单例Bean对象 */ public static R getSingletonBean(String beanName, Class type) { if (null == beanName || null == type || beanName.trim().isEmpty()) return null; DefaultListableBeanFactory beanFactory = getBeanFactory(); if (!beanFactory.containsSingleton(beanName)) return null; return type.cast(beanFactory.getSingleton(beanName)); } /** * 获取Spring上下文中的Bean定义 * * @param beanName BeanId * @return Bean定义对象 * @description 从Bean定义字典beanDefinitionMap中获取指定Bean名称对应的Bean定义 */ public static BeanDefinition getBeanDefinition(String beanName) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanName || null == applicationContext || beanName.trim().isEmpty()) return null; if (!applicationContext.containsBeanDefinition(beanName)) return null; return applicationContext.getBeanDefinition(beanName); } /** * 移除Spring上下文中的Bean定义 * * @param beanName BeanId * @description 从整个容器中移除指定Bean名称的Bean定义和单例Bean对象 */ public static void removeBean(String beanName) { if (null == beanName || beanName.trim().isEmpty()) return; DefaultListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsBeanDefinition(beanName)) { beanFactory.removeBeanDefinition(beanName); } else { beanFactory.destroySingleton(beanName); } } /** * 移除Spring上下文中的所有兼容Bean定义 * * @param beanType 兼容Bean类型 * @return 移除的兼容类型Bean数量 * @description 从整个容器中移除指定兼容类型的Bean定义和单例Bean对象 */ public static Integer removeBean(Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanType || null == applicationContext) return null; String[] beanNames = applicationContext.getBeanNamesForType(beanType, true, true); if (null == beanNames || 0 == beanNames.length) return 0; for (String beanName : beanNames) removeBean(beanName); return beanNames.length; } /** * 检查给定Bean名称对应的Bean是否为单例Bean * * @param beanName Bean名称(BeanId) * @return 是否为单例Bean */ public static Boolean isSingleton(String beanName) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanName || null == applicationContext || beanName.trim().isEmpty()) return null; return applicationContext.isSingleton(beanName); } /** * 判断Spring上下文中是否存在指定名称的Bean对象 * * @param beanType Bean名称 * @return 逻辑类型 * @description 检查整个容器中是否存在指定Bean名称的Bean对象 */ public static Boolean hasBean(String beanName) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanName || null == applicationContext || beanName.trim().isEmpty()) return null; return applicationContext.containsBean(beanName); } /** * 判断Spring上下文中是否存在指定兼容类型的Bean对象 * * @param beanType Bean类型 * @return 逻辑类型 * @description 检查整个容器中是否存在指定兼容类型的Bean对象 */ public static Boolean hasBean(Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanType || null == applicationContext) return null; String[] beanNames = applicationContext.getBeanNamesForType(beanType, true, true); return null == beanNames || 0 == beanNames.length ? false : true; } /** * 判断Spring上下文中是否存在指定兼容类型的唯一Bean对象 * * @param beanType Bean类型 * @return 逻辑类型 * @description 检查整个容器中是否存在指定兼容类型的唯一Bean对象 */ public static Boolean hasUniqueBean(Class beanType) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanType || null == applicationContext) return null; String[] beanNames = applicationContext.getBeanNamesForType(beanType, true, true); return null == beanNames || 0 == beanNames.length ? false : 1 < beanNames.length ? false : true; } /** * 判断Spring上下文中是否存在指定名称的单例Bean对象 * * @param beanType Bean名称 * @return 逻辑类型 * @description 检查单例对象字典singletonObjects中是否存在指定的名称的单例Bean对象 */ public static Boolean hasSingletonBean(String beanName) { if (null == beanName || beanName.trim().isEmpty()) return null; DefaultListableBeanFactory beanFactory = getBeanFactory(); return beanFactory.containsSingleton(beanName); } /** * 判断Spring上下文中是否存在指定名称的Bean定义 * * @param beanType Bean名称 * @return 逻辑类型 * @description 检查Bean定义字典beanDefinitionMap中是否存在指定的名称的Bean定义 */ public static Boolean hasBeanDefinition(String beanName) { GenericApplicationContext applicationContext = getApplicationContext(); if (null == beanName || null == applicationContext || beanName.trim().isEmpty()) return null; return applicationContext.containsBeanDefinition(beanName); } /** * 环境中是否配置指定的属性 * * @param key 键 * @return 逻辑类型 */ public static Boolean hasProperty(String key) { return getEnvironment().containsProperty(key); } /** * 环境中是否配置指定的属性前缀 * * @param prefix 键前缀 * @return 是否存在指定的属性前缀 */ public static Boolean hasPropertyPrefix(String prefix) { for (PropertySource propertySource : getEnvironment().getPropertySources()) { Object source = propertySource.getSource(); if (null == source || !(source instanceof Map)) continue; for (Object key : ((Map) source).keySet()) if (key.toString().startsWith(prefix)) return true; } return false; } /** * 获取环境配置 * * @param key 键 * @return 字串类型 */ public static String getProperty(String key) { return getProperty(key, (String) null, (String[]) null); } /** * 获取环境配置 * * @param key 键 * @param defaultValue 默认值 * @return 字串类型 */ public static String getProperty(String key, String defaultValue) { return getProperty(key, (String) null, defaultValue); } /** * 获取环境配置 * * @param key 键 * @param defaultKey 默认键 * @param defaultValue 默认值 * @return 字串类型 */ public static String getProperty(String key, String defaultKey, String... defaultValue) { return getProperty(key, defaultKey, String.class, defaultValue); } /** * 获取环境配置 * * @param key 键 * @param defaultValue 默认值 * @return 对象类型 */ public static Object getProperty(String key, Object... defaultValue) { return getProperty(key, Object.class, defaultValue); } /** * 获取环境配置 * * @param key 键 * @param defaultKey 默认键 * @param defaultValue 默认值 * @return 对象类型 */ public static Object getProperty(String key, String defaultKey, Object... defaultValue) { return getProperty(key, defaultKey, Object.class, defaultValue); } /** * 获取环境配置 * * @param key 键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getProperty(String key, Class returnType, R... defaultValue) { return getProperty(key, (String) null, returnType, defaultValue); } /** * 获取环境配置 * * @param key 键 * @param defaultKey 默认键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getProperty(String key, String defaultKey, Class returnType, R... defaultValue) { R defaultVal = (null == defaultValue || 0 == defaultValue.length) ? null : defaultValue[0]; StandardEnvironment env = getEnvironment(); String value = env.getProperty(key); if (null == value && null != defaultKey) value = env.getProperty(defaultKey); if (null == value) return defaultVal; String stringValue = value.toString().trim(); try { if (Number.class.isAssignableFrom(returnType)) { return returnType.getConstructor(String.class).newInstance(stringValue); } else if (Date.class.isAssignableFrom(returnType)) { return returnType.getConstructor(long.class).newInstance(DateUtil.stringToMillSeconds(stringValue)); } else if (Boolean.class == returnType) { return (R) Boolean.valueOf(stringValue); } else if (Character.class == returnType) { return (R) Character.valueOf(stringValue.charAt(0)); } else { return (R) stringValue; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 获取环境配置 * * @param prefix 配置前缀 * @param defaultValue 默认值 * @return 字典类型 * @throws Exception */ public static Map getProperties(String prefix, Map... defaultValue) throws Exception { return getProperties(prefix, null, Map.class, null, defaultValue); } /** * 获取环境配置 * * @param prefix 配置前缀 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 实体类型或字典类型 * @throws Exception */ public static R getProperties(String prefix, Class returnType, R... defaultValue) throws Exception { return getProperties(prefix, null, returnType, null, defaultValue); } /** * 获取环境配置 * * @param prefix 配置前缀 * @param returnType 返回类型 * @param valueType 字典值类型 * @param defaultValue 默认值 * @return 实体类型或字典类型 * @throws Exception */ public static R getProperties(String prefix, Class returnType, Class valueType, R... defaultValue) throws Exception { return getProperties(prefix, null, returnType, valueType, defaultValue); } /** * 获取环境配置 * * @param prefix 配置前缀 * @param defaultPrefix 默认配置前缀 * @param returnType 返回类型 * @param valueType 字典值类型 * @param defaultValue 默认值 * @return 实体类型或字典类型 * @throws Exception */ public static R getProperties(String prefix, String defaultPrefix, Class returnType, Class valueType, R... defaultValue) throws Exception { Map dict = new HashMap(); R defaultVal = (null == defaultValue || 0 == defaultValue.length) ? null : defaultValue[0]; // 获取环境配置 Map properties = getPropertiesConfig(); // 过滤出前缀配置组 properties.entrySet().stream().filter(entry -> entry.getKey().startsWith(prefix)).forEach(entry -> { String attrName = entry.getKey().substring(prefix.length()); if (!prefix.endsWith(".")) attrName = attrName.substring(attrName.indexOf(".") + 1); dict.put(attrName, entry.getValue()); }); if (0 == dict.size() && null != defaultPrefix) { properties.entrySet().stream().filter(entry -> entry.getKey().startsWith(defaultPrefix)).forEach(entry -> { String attrName = entry.getKey().substring(defaultPrefix.length()); if (!defaultPrefix.endsWith(".")) attrName = attrName.substring(attrName.indexOf(".") + 1); dict.put(attrName, entry.getValue()); }); } if (0 == dict.size()) return defaultVal; // 按实体类型解析 if (!Map.class.isAssignableFrom(returnType)) { R r = returnType.newInstance(); dict.forEach((key, value) -> recursionInjection(key, value, r)); return r; } // 按普通Map接口类型解析 if (null == valueType || CommonUtil.isSimpleType(valueType)) { if (returnType.isInterface()) return returnType.cast(dict); R r = returnType.newInstance(); Method method = CommonUtil.findMethod(returnType, "putAll", Map.class); method.invoke(r, dict); return r; } // 按嵌套实体的Map接口类型解析 Map returnMap = new HashMap(); dict.forEach((key, value) -> { String[] attrs = CommonUtil.DOT_REGEX.split(key); if (attrs.length != 2) return; String mapKey = CommonUtil.dashToHump(attrs[0]); String attrName = CommonUtil.dashToHump(attrs[1]); E e = returnMap.get(mapKey); try { if (null == e) returnMap.put(mapKey, e = valueType.newInstance()); Field field = CommonUtil.findField(valueType, attrName); field.set(e, CommonUtil.transferType(value, field.getType())); } catch (Exception e1) { e1.printStackTrace(); } }); return returnType.cast(returnMap); } /** * 设置Web应用域缓存 * * @param key 键 * @param value 值 */ public static void setAttribute(String key, Object value) { getServletContext().setAttribute(key, value); } /** * 获取Web应用域缓存 * * @param key 键 * @param defaultValue 默认值 * @return 对象类型 */ public static Object getAttribute(String key, Object... defaultValue) { return getAttribute(key, Object.class, defaultValue); } /** * 获取Web应用域缓存 * * @param key 键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getAttribute(String key, Class returnType, R... defaultValue) { return getAttribute(key, null, returnType, defaultValue); } /** * 获取Web应用域缓存 * * @param key 键 * @param defaultKey 默认键 * @param returnType 返回类型 * @param defaultValue 默认值 * @return 泛化类型 */ public static R getAttribute(String key, String defaultKey, Class returnType, R... defaultValue) { R defaultVal = (null == defaultValue || 0 == defaultValue.length) ? null : defaultValue[0]; ServletContext servletContext = getServletContext(); Object value = servletContext.getAttribute(key); if (null == value && null != defaultKey) value = servletContext.getAttribute(defaultKey); if (null == value) return defaultVal; return returnType.cast(value); } /** * 获取当前位置上下文 * * @param levels 线程栈层级 * @return 位置上下文字典 */ public static StackTraceElement getPositionContext(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; return Thread.currentThread().getStackTrace()[level]; } /** * 获取当前文件名 * * @return 当前源文件名 */ public static String getCurrentFileName(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; return Thread.currentThread().getStackTrace()[level].getFileName(); } /** * 获取当前文件行号 * * @return 当前文件行号 */ public static Integer getCurrentLineNumber(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; return Thread.currentThread().getStackTrace()[level].getLineNumber(); } /** * 获取当前类名称 * * @return 当前类对象 * @throws ClassNotFoundException */ public static Class getCurrentClass(Integer... levels) throws ClassNotFoundException { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; String className = Thread.currentThread().getStackTrace()[level].getClassName(); return Class.forName(className); } /** * 获取当前类名称 * * @return 当前类名 */ public static String getCurrentClassName(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; return Thread.currentThread().getStackTrace()[level].getClassName(); } /** * 获取当前方法 * * @return 当前方法对象 * @throws ClassNotFoundException */ public static Method getCurrentMethod(Integer... levels) throws ClassNotFoundException { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; StackTraceElement threadStack = Thread.currentThread().getStackTrace()[level]; String methodName = threadStack.getMethodName(); Method[] methods = Class.forName(threadStack.getClassName()).getDeclaredMethods(); for (Method method : methods) if (methodName.equals(method.getName())) return method; return null; } /** * 获取当前方法名称 * * @return 当前方法名 */ public static String getCurrentMethodName(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; return Thread.currentThread().getStackTrace()[level].getMethodName(); } /** * 获取当前类路径 返回此方法调用方的类路径目录 * * @return 字串类型 */ public static String getCurrentClassPath(Integer... levels) { Integer level = null == levels || 0 == levels.length ? 2 : null == levels[0] || levels[0] < 2 ? 2 : levels[0]; String callClassName = Thread.currentThread().getStackTrace()[level].getClassName(); String callPkgPath = callClassName.substring(0, callClassName.lastIndexOf('.')).replace('.', File.separatorChar); return new StringBuilder(getClassPathRoot()).append(File.separatorChar).append(callPkgPath).toString(); } /** * 获取参数包对应的类路径目录 * * @param packagePath 包路径 * @return 字串类型 */ public static String getPackageClassPath(String packagePath) { String packageDir = packagePath.replace('.', File.separatorChar); return new StringBuilder(getClassPathRoot()).append(File.separatorChar).append(packageDir).toString(); } /** * 获取工程类路径根目录 * * @return 字串类型 */ public static String getClassPathRoot() { try { return new File(ApplicationUtil.class.getResource("/").toURI()).getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); } return getClassPathList().get(0); } /** * 获取类路径目录列表 * * @return 路径列表 */ public static List getClassPathList() { String classpaths = getJVMProperties().get(PROJECT_CLASS_PATH).toString(); return Arrays.asList(CLASSPATH_SEPARATOR_REGEX.split(classpaths)); } /** * 获取工程脚本目录 * * @param isDecode 是否需要中文解码 * @description 按常规服务器目录编排获取 * @return 工程脚本目录 */ public static File getBinPath(Boolean... isDecode) { return new File(getProjectPath(isDecode), "bin"); } /** * 获取工程配置目录 * * @param isDecode 是否需要中文解码 * @description 按常规服务器目录编排获取 * @return 工程配置目录 */ public static File getConfPath(Boolean... isDecode) { return new File(getProjectPath(isDecode), "conf"); } /** * 获取工程目录 * * @param isDecode 是否需要中文解码 * @description 按常规服务器目录编排获取 * @return 工程目录 */ public static File getProjectPath(Boolean... isDecode) { return getLibPath(isDecode).getParentFile(); } /** * 获取工程库目录 * * @param isDecode 是否需要中文解码 * @description 按常规服务器目录编排获取 * @return 工程库目录 */ public static File getLibPath(Boolean... isDecode) { return getJarPkgFile(isDecode).getParentFile(); } /** * 获取当前JAR包绝对路径文件 * * @param isDecode 是否需要中文解码 * @return 绝对路径文件 */ public static File getJarPkgFile(Boolean... isDecode) { String jarPkgPath = getJarPkgPath(isDecode); return new File(jarPkgPath); } /** * 获取当前JAR包绝对路径 * * @param isDecode 是否需要中文解码 * @return JAR包绝对路径 */ public static String getJarPkgPath(Boolean... isDecode) { boolean decode = null == isDecode || 0 == isDecode.length || null == isDecode[0] ? false : isDecode[0]; String currentClassPath = ApplicationUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); try { if (decode) currentClassPath = java.net.URLDecoder.decode(currentClassPath, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } String jarUriPath = currentClassPath; int firstSep = currentClassPath.indexOf("!"); if (-1 != firstSep) jarUriPath = currentClassPath.substring(0, firstSep); String prefix = jarUriPath.substring(0, 3); if (PATH_PREFIX.matcher(prefix).matches()) { return new File(jarUriPath.substring(1)).getAbsolutePath(); } else { if (!isWindows()) { return new File(jarUriPath).getAbsolutePath(); } else { try { return new File(new URI(jarUriPath)).getAbsolutePath(); } catch (URISyntaxException e) { throw new RuntimeException(e); } } } } /** * 获取工程类路径绝对路径目录 * * @return 类路径绝对路径目录 */ public static File getClassPathRealFile() { String realPath = getClassPathRealPath(); if (null == realPath) return null; return new File(realPath); } /** * 获取工程类路径绝对路径 * * @return 类路径绝对路径 */ public static String getClassPathRealPath() { String location = null; try { location = ApplicationUtil.class.getProtectionDomain().getCodeSource().getLocation().toURI().toString(); } catch (URISyntaxException e) { e.printStackTrace(); } if (null == location) return null; return location.startsWith("file:") ? location.substring(5) : location; } /** * 递归获取参数包路径下的所有类 * * @param packagePath 包路径(使用'.'分隔) * @return 类表 * @throws ClassNotFoundException */ public static ArrayList> getClasses(String packagePath) throws ClassNotFoundException { if (null == packagePath || packagePath.trim().isEmpty()) return null; String classPath = new StringBuilder(getClassPathRoot()).append(File.separatorChar).toString(); return getClasses(classPath,new File(new StringBuilder(classPath).append(packagePath.replace('.', File.separatorChar)).toString())); } /** * 递归获取指定目录下的 * * @param classPath 类路径目录(使用'/'分隔并以'/'结尾) * @param directory 目录绝对路径 * @return 类表 * @throws ClassNotFoundException */ public static ArrayList> getClasses(String classPath, File directory) throws ClassNotFoundException { if (null == classPath || null == directory || 0 == classPath.trim().length() || directory.isFile()) return null; ArrayList> list = new ArrayList>(); for (File file : directory.listFiles()) { if (file.isFile()) { String fullPath = file.getAbsolutePath(); String packgeName = fullPath.substring(classPath.trim().length(), fullPath.length() - 6) .replace(File.separatorChar, '.'); list.add(Class.forName(packgeName)); continue; } ArrayList> tmpList = getClasses(classPath, file); if (null == tmpList || 0 == tmpList.size()) continue; list.addAll(tmpList); } return list; } /** * 获取当前Jvm进程ID */ public static Integer getJvmProcessID() { String jvmName = ManagementFactory.getRuntimeMXBean().getName(); if (null == jvmName) return null; jvmName = jvmName.trim(); if (0 == jvmName.length()) return null; if (-1 == jvmName.indexOf("@")) return null; return Integer.parseInt(EMAIL_SEPARATOR_REGEX.split(jvmName)[0]); } /** * 当前系统是否为Windows */ public static final boolean isWindows() { return ManagementFactory.getOperatingSystemMXBean().getName().trim().toLowerCase().startsWith("win") ? true : false; } /** * 强制杀掉子进程 * * @param process 子进程ID */ public static final Boolean forceKillProcess(long processId) { return killProcess(processId, true); } /** * 平滑杀掉子进程 * * @param process 子进程ID */ public static final Boolean gracefulKillProcess(long processId) { return killProcess(processId, false); } /** * 杀掉子进程 * * @param processId 子进程ID * @param force 是否强制杀掉(true:强制,false:平滑) */ public static final Boolean killProcess(long processId, boolean force) { String osName = ManagementFactory.getOperatingSystemMXBean().getName().trim().toLowerCase(); try { if (osName.startsWith("win")) { if (force) { return Runtime.getRuntime().exec("taskkill /T /F /PID " + processId).waitFor(15, TimeUnit.SECONDS); } else { return Runtime.getRuntime().exec("taskkill /T /PID " + processId).waitFor(15, TimeUnit.SECONDS); } } else { if (force) { return Runtime.getRuntime().exec("kill -9 " + processId).waitFor(15, TimeUnit.SECONDS); } else { return Runtime.getRuntime().exec("kill -sigterm " + processId).waitFor(15, TimeUnit.SECONDS); } } } catch (Exception e) { e.printStackTrace(); return false; } } /** * 获取Spring切面执行优先级 * * @param aspectBeanName 切面Bean名称 * @param aspectBeanType 切面Bean类型 * @return 切面优先级顺序 */ public static Integer getAspectOrder(String aspectBeanName) { Object aspectBean = ApplicationUtil.getBean(aspectBeanName); return Ordered.class.isInstance(aspectBean) ? ((Ordered) aspectBean).getOrder() : null; } /** * 修改Spring事务切面的执行顺序 * * @param order 切面执行优先级 */ public static void setTransactionAdvisorOrder(Integer order) { Class advisorType = null; try { advisorType = Class.forName("org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } if (null == advisorType) return; Object advisor = null; if (null == (advisor = getBean("org.springframework.transaction.config.internalTransactionAdvisor",advisorType))) return; try { Method setOrder = advisorType.getDeclaredMethod("setOrder", int.class); if (null != order) { setOrder.invoke(advisor, order); } else { setOrder.invoke(advisor, Ordered.HIGHEST_PRECEDENCE); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 注册单例Bean到Spring上下文 * * @param bean 单例Bean对象 */ public static void registerSingleton(Object bean) { String simpleName = bean.getClass().getSimpleName(); String beanName = CommonUtil.lowerFirstChar(simpleName); registerSingleton(beanName, bean); } /** * 注册单例Bean到Spring上下文 * * @param beanName Bean名称(BeanId) * @param bean 单例Bean对象 */ public static void registerSingleton(String beanName, Object bean) { registerSingleton(beanName, bean, BeanIdMode.BEAN_NAME); } /** * 注册单例Bean到Spring上下文 * * @param beanName Bean名称(BeanId) * @param bean 单例Bean对象 * @param removeNonUnique 重复Bean定义的移除模式 * @description 注册单例Bean定义和单例Bean对象 */ public static void registerSingleton(String beanName, Object bean, BeanIdMode removeNonUnique) { if (null == bean) throw new RuntimeException("bean can not be null..."); if (null == beanName || beanName.trim().isEmpty()) throw new RuntimeException("beanName can not be empty..."); registerBeanDefinition(beanName, bean.getClass(), removeNonUnique); registerSingletonBean(beanName, bean); } /** * 注册单例Bean到Spring上下文 * * @param beanName Bean名称(BeanId) * @param bean 单例Bean对象 * @description 注册单例Bean对象 */ public static void registerSingletonBean(String beanName, Object bean) { DefaultListableBeanFactory beanFactory = getBeanFactory(); if (null == beanFactory) return; beanFactory.registerSingleton(beanName, bean); } /** * 注册Bean到Spring上下文 * * @param beanType Bean类型 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(Class beanType) { registerBeanDefinition(beanType, new HashMap()); } /** * 注册Bean到Spring上下文 * * @param beanName Bean名称(beanId) * @param beanType Bean类型 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(String beanName, Class beanType) { registerBeanDefinition(beanName, beanType, new HashMap()); } /** * 注册Bean到Spring上下文 * * @param beanType Bean类型 * @param properties Bean属性字典 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(Class beanType, Map properties) { registerBeanDefinition(beanType, properties, BeanIdMode.BEAN_NAME); } /** * 注册Bean到Spring上下文 * * @param beanName Bean名称(beanId) * @param beanType Bean类型 * @param removeNonUnique 重复Bean定义的移除模式 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(String beanName, Class beanType, BeanIdMode removeNonUnique) { registerBeanDefinition(beanType, beanName, new HashMap(), removeNonUnique); } /** * 注册Bean到Spring上下文 * * @param beanName Bean名称(beanId) * @param beanType Bean类型 * @param properties Bean属性字典 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(String beanName, Class beanType, Map properties) { registerBeanDefinition(beanType, beanName, properties, BeanIdMode.BEAN_NAME); } /** * 注册Bean到Spring上下文 * * @param beanType Bean类型 * @param properties Bean属性字典 * @param removeNonUnique 重复Bean定义的移除模式 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(Class beanType, Map properties, BeanIdMode removeNonUnique) { registerBeanDefinition(beanType, null, properties, removeNonUnique); } /** * 注册Bean到Spring上下文 * * @param beanType Bean类型 * @param beanName Bean名称(beanId) * @param properties Bean属性字典 * @param removeNonUnique 重复Bean定义的移除模式 * @param constructorArgs Bean类构造器参数列表 * @return 泛化类型 * @description 注册Bean定义 */ public static void registerBeanDefinition(Class beanType, String beanName, Map properties, BeanIdMode removeNonUnique, Object... constructorArgs) { DefaultListableBeanFactory beanFactory = getBeanFactory(); if (null == beanFactory) return; // 获取Bean参数定义 Object scope = null; Object lazyInit = null; Object initMethod = null; Object dependsBeanId = null; Object autowireMode = null; Object destoryMethod = null; if (null != properties && 0 != properties.size()) { scope = properties.remove("scope"); lazyInit = properties.remove("lazyInit"); initMethod = properties.remove("initMethod"); dependsBeanId = properties.remove("dependsBeanId"); autowireMode = properties.remove("autowireMode"); destoryMethod = properties.remove("destoryMethod"); } // 设置Bean定义参数 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanType); beanDefinitionBuilder.setAutowireMode( null == autowireMode ? AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE : (Integer) autowireMode); beanDefinitionBuilder.setScope(null == scope ? BeanDefinition.SCOPE_SINGLETON : (String) scope); beanDefinitionBuilder.setLazyInit(null == lazyInit ? true : (Boolean) lazyInit); if (null != dependsBeanId) beanDefinitionBuilder.addDependsOn((String) dependsBeanId); if (null != initMethod) beanDefinitionBuilder.setInitMethodName((String) initMethod); if (null != destoryMethod) beanDefinitionBuilder.setDestroyMethodName((String) destoryMethod); // 添加构造参数值 if (null != constructorArgs && 0 != constructorArgs.length) { for (Object argValue : constructorArgs) beanDefinitionBuilder.addConstructorArgValue(argValue); } // 设置Bean属性值 if (null != properties) properties.forEach((key, value) -> beanDefinitionBuilder.addPropertyValue(key, value)); // 设置Bean的名字(BeanId) if (null == beanName) beanName = CommonUtil.lowerFirstChar(beanType.getSimpleName()); // 移除已经包含此Bean的定义 if (removeNonUnique == BeanIdMode.BEAN_NAME) { removeBean(beanName); } else { removeBean(beanType); } // 注册Bean到容器 beanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getRawBeanDefinition()); } /** * 包装实体对象(递归处理对象图结构) * * @param key 复合类型Key * @param value 最终设定的简单类型值 */ public static void recursionInjection(String key, Object value, R r) { String curAttrName = key; String nextAttrName = null; int index = key.indexOf("."); if (-1 != index) { curAttrName = key.substring(0, index); nextAttrName = key.substring(index + 1); } String fieldName = CommonUtil.dashToHump(curAttrName); Class returnType = r.getClass(); try { Field field = CommonUtil.findField(returnType, fieldName); if (null == field) return; Class attrType = field.getType(); Boolean isSimpleType = CommonUtil.isSimpleType(attrType); if (null != nextAttrName && (isSimpleType || attrType.isArray())) return; // 简单类型设值 if (isSimpleType) { field.set(r, CommonUtil.transferType(value, field.getType())); return; } // 字符数组类型赋值 if (char[].class == attrType || Character[].class == attrType) { field.set(r, CommonUtil.transferArray(value.toString().toCharArray(), attrType.getComponentType())); return; } // 数组类型设值 if (attrType.isArray()) { Class eleType = attrType.getComponentType(); String[] array = CommonUtil.COMMA.split(value.toString()); Object arrValue = Array.newInstance(eleType, array.length); for (int i = 0; i < array.length; i++) { Object transferValue = CommonUtil.transferType(array[i], eleType); Array.set(arrValue, i, transferValue); } field.set(r, arrValue); return; } // 集合类型设值(集合泛型为简单类型) if (Collection.class.isAssignableFrom(attrType)) { Collection cols = null; if (attrType.isInterface()) { cols = List.class.isAssignableFrom(attrType) ? new ArrayList() : new HashSet(); } else { try { cols = (Collection) attrType.newInstance(); } catch (Exception e) { e.printStackTrace(); } } Class[] genericParams = CommonUtil.getGenericClass(field); String[] array = CommonUtil.COMMA.split(value.toString()); if (null == genericParams || 0 == genericParams.length) { cols.add(Arrays.asList(array)); } else { Object newArray = CommonUtil.transferArray(array, genericParams[0]); cols.addAll(CommonUtil.arrayToList(newArray)); } field.set(r, cols); return; } // 字典类型设值(字典泛型为简单类型) if (Map.class.isAssignableFrom(attrType)) { Map map = null; if (attrType.isInterface()) { map = new HashMap(); } else { try { map = (Map) attrType.newInstance(); } catch (Exception e) { e.printStackTrace(); } } Map readMap = CommonUtil.jsonStrToJava(value.toString(), Map.class); Class[] genericParams = CommonUtil.getGenericClass(field); if (null == genericParams || 2 != genericParams.length) { map.putAll(readMap); } else { for (Map.Entry entry : (Set) readMap.entrySet()) { Object attrName = CommonUtil.transferType(entry.getKey(), genericParams[0]); Object attrValue = CommonUtil.transferType(entry.getValue(), genericParams[1]); map.put(attrName, attrValue); } } field.set(r, map); return; } // 复合类型设值 recursionInjection(nextAttrName, value, attrType.newInstance()); } catch (Exception e) { e.printStackTrace(); } } }