Răsfoiți Sursa

threadFactory

zhourui 5 ani în urmă
părinte
comite
bdda7a87aa
23 a modificat fișierele cu 582 adăugiri și 121 ștergeri
  1. 8 14
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/AbstractContext.java
  2. 53 46
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Applications.java
  3. 7 5
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Context.java
  4. 3 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/AbstractActionApplication.java
  5. 8 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/ThreadJaxrsFilter.java
  6. 2 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/WrapBoolean.java
  7. 28 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionAlive.java
  8. 23 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionParameter.java
  9. 23 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionStop.java
  10. 7 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/BaseAction.java
  11. 75 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ThreadAction.java
  12. 14 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/thread/ParameterRunnable.java
  13. 251 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/thread/ThreadFactory.java
  14. 7 4
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionListLike.java
  15. 9 6
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionListLikePinyin.java
  16. 8 7
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionListLike.java
  17. 10 9
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionListLikePinyin.java
  18. 9 6
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/person/ActionListLike.java
  19. 11 8
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/person/ActionListLikePinyin.java
  20. 8 5
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/role/ActionListLike.java
  21. 8 5
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/role/ActionListLikePinyin.java
  22. 5 3
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/unit/ActionListLike.java
  23. 5 2
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/unit/ActionListLikePinyin.java

+ 8 - 14
o2server/x_base_core_project/src/main/java/com/x/base/core/project/AbstractContext.java

@@ -1,39 +1,33 @@
 package com.x.base.core.project;
 
 import com.x.base.core.project.annotation.Module;
+import com.x.base.core.project.thread.ThreadFactory;
 
 public abstract class AbstractContext {
-	/** Applications资源 */
+
+	// Applications资源
 	protected volatile Applications applications;
 
 	protected static final String INITPARAMETER_PORJECT = "project";
 
 	public abstract Applications applications() throws Exception;
 
-//	protected static String getName(Class<?> clz) throws Exception {
-//		Module module = clz.getAnnotation(Module.class);
-//		return module.name();
-//	}
+	protected ThreadFactory threadFactory;
+
+	public abstract ThreadFactory threadFactory();
 
-	/* 应用类 */
+	// 应用类
 	protected Class<?> clazz;
 
 	public Class<?> clazz() {
 		return this.clazz;
 	}
 
-//	/* 应用类对象 */
-//	protected Deployable clazzInstance;
-
-	/* 模块指示类 */
+	// 模块指示类
 	protected Module module;
 
 	public Module module() {
 		return this.module;
 	}
 
-//	public Deployable clazzInstance() {
-//		return this.clazzInstance;
-//	}
-
 }

+ 53 - 46
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Applications.java

@@ -14,6 +14,9 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.zip.CRC32;
 
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.config.Nodes;
 import com.x.base.core.project.connection.ActionResponse;
@@ -27,9 +30,6 @@ import com.x.base.core.project.tools.DefaultCharset;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.StringTools;
 
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-
 public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList<Application>> {
 
 	private static Logger logger = LoggerFactory.getLogger(Applications.class);
@@ -111,12 +111,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public ActionResponse getQuery(Boolean xdebugger, String applicationName, String uri, String seed)
 			throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -125,7 +126,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 								.append(":" + port);
 					}
 					buffer.append("/x_program_center/jaxrs/");
-					return CipherConnectionAction.get(xdebugger, buffer.toString()+ CipherConnectionAction.trim(uri));
+					return CipherConnectionAction.get(xdebugger, buffer.toString() + CipherConnectionAction.trim(uri));
 
 				}
 			}
@@ -183,13 +184,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public byte[] getQueryBinary(Boolean xdebugger, String applicationName, String uri, String seed) throws Exception {
 		String name = this.findApplicationName(applicationName);
-
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -257,12 +258,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public ActionResponse deleteQuery(Boolean xdebugger, String applicationName, String uri, String seed)
 			throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -331,12 +333,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public byte[] deleteQueryBinary(Boolean xdebugger, String applicationName, String uri, String seed)
 			throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -347,7 +350,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 					buffer.append("/x_program_center/jaxrs/");
 
 					return CipherConnectionAction.deleteBinary(xdebugger,
-							buffer.toString()  + CipherConnectionAction.trim(uri));
+							buffer.toString() + CipherConnectionAction.trim(uri));
 				}
 			}
 		}
@@ -407,12 +410,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public ActionResponse postQuery(Boolean xdebugger, String applicationName, String uri, Object body, String seed)
 			throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -422,7 +426,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 					}
 					buffer.append("/x_program_center/jaxrs/");
 
-					return CipherConnectionAction.post(xdebugger, buffer.toString()  + CipherConnectionAction.trim(uri),
+					return CipherConnectionAction.post(xdebugger, buffer.toString() + CipherConnectionAction.trim(uri),
 							body);
 				}
 			}
@@ -483,12 +487,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public byte[] postQueryBinary(Boolean xdebugger, String applicationName, String uri, Object body, String seed)
 			throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -499,7 +504,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 					buffer.append("/x_program_center/jaxrs/");
 
 					return CipherConnectionAction.postBinary(xdebugger,
-							buffer.toString()  + CipherConnectionAction.trim(uri), body);
+							buffer.toString() + CipherConnectionAction.trim(uri), body);
 				}
 			}
 		}
@@ -565,12 +570,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public byte[] postQueryMultiPartBinary(Boolean xdebugger, String applicationName, String uri,
 			Collection<FormField> formFields, Collection<FilePart> fileParts, String seed) throws Exception {
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -642,13 +648,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public ActionResponse putQuery(Boolean xdebugger, String applicationName, String uri, Object body, String seed)
 			throws Exception {
-
-		if(applicationName.equalsIgnoreCase("x_program_center")|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
+		if (applicationName.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| applicationName.equalsIgnoreCase(x_program_center.class.getName())) {
 			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -688,10 +694,11 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 				return str;
 			}
 		}
-		if(name.equalsIgnoreCase("x_program_center")|| name.equalsIgnoreCase(x_program_center.class.getName())) {
-			return "x_program_center";
+		if (name.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| name.equalsIgnoreCase(x_program_center.class.getName())) {
+			return x_program_center.class.getName();
 		}
-			return null;
+		return null;
 	}
 
 	public Application findApplicationWithNode(String className, String node) throws Exception {
@@ -703,7 +710,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 		return null;
 	}
 
-	public Application randomWithWeight(String className) throws Exception {
+	public Application randomWithWeight(String className) throws IllegalStateException {
 		List<Application> list = this.get(className);
 		if (ListTools.isNotEmpty(list)) {
 			if (list.size() == 1) {
@@ -720,10 +727,10 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 			Application application = tree.tailMap(random.nextInt(++cursor), true).firstEntry().getValue();
 			return application;
 		}
-		throw new Exception("randomWithWeight error: " + className + ".");
+		throw new IllegalStateException("randomWithWeight error: " + className + ".");
 	}
 
-	public Application randomWithScheduleWeight(String className) throws Exception {
+	public Application randomWithScheduleWeight(String className) throws IllegalStateException {
 		List<Application> list = this.get(className);
 		if (ListTools.isNotEmpty(list)) {
 			if (list.size() == 1) {
@@ -740,7 +747,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 			Application application = tree.tailMap(random.nextInt(++cursor), true).firstEntry().getValue();
 			return application;
 		}
-		throw new Exception("randomWithScheduleWeight error: " + className + ".");
+		throw new IllegalStateException("randomWithScheduleWeight error: " + className + ".");
 	}
 
 	public Application randomWithSeed(String className, String seed) throws Exception {
@@ -772,12 +779,13 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 
 	public String describeApi(String name) throws Exception {
 		String urlDescribeApiJson = "";
-		if(name.equalsIgnoreCase("x_program_center")|| name.equalsIgnoreCase(x_program_center.class.getName())) {
-			 Nodes nodes = Config.nodes();
+		if (name.equalsIgnoreCase(x_program_center.class.getSimpleName())
+				|| name.equalsIgnoreCase(x_program_center.class.getName())) {
+			Nodes nodes = Config.nodes();
 			for (String node : nodes.keySet()) {
-				if (nodes.get(node).getCenter().getEnable()) {
+				if (BooleanUtils.isTrue(nodes.get(node).getCenter().getEnable())) {
 					Integer port = nodes.get(node).getCenter().getPort();
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					if (BooleanUtils.isTrue(nodes.get(node).getCenter().getSslEnable())) {
 						buffer.append("https://").append(StringUtils.isNotEmpty(node) ? node : "127.0.0.1")
 								.append(":" + port);
@@ -790,13 +798,12 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 					break;
 				}
 			}
-		}else {
+		} else {
 			String applicationName = this.findApplicationName(name);
 			if (StringUtils.isEmpty(applicationName)) {
 				throw new Exception("getDescribe can not find application with name:" + name + ".");
 			}
 			Application application = this.randomWithWeight(applicationName);
-			//return HttpConnection.getAsString(application.getUrlDescribeApiJson(), null);
 			urlDescribeApiJson = application.getUrlDescribeApiJson();
 		}
 		return HttpConnection.getAsString(urlDescribeApiJson, null);

+ 7 - 5
o2server/x_base_core_project/src/main/java/com/x/base/core/project/Context.java

@@ -41,9 +41,9 @@ import com.x.base.core.project.schedule.JobReportListener;
 import com.x.base.core.project.schedule.ScheduleLocalRequest;
 import com.x.base.core.project.schedule.ScheduleRequest;
 import com.x.base.core.project.schedule.SchedulerFactoryProperties;
+import com.x.base.core.project.thread.ThreadFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SslTools;
-import com.x.base.core.project.tools.StringTools;
 
 public class Context extends AbstractContext {
 
@@ -175,6 +175,10 @@ public class Context extends AbstractContext {
 		return this.applications;
 	}
 
+	public ThreadFactory threadFactory() {
+		return this.threadFactory;
+	}
+
 	/* 队列 */
 	private List<AbstractQueue<?>> queues;
 
@@ -188,7 +192,7 @@ public class Context extends AbstractContext {
 	}
 
 	public static Context concrete(ServletContextEvent servletContextEvent) throws Exception {
-		/* 强制忽略ssl服务器认证 */
+		// 强制忽略ssl服务器认证
 		SslTools.ignoreSsl();
 		ServletContext servletContext = servletContextEvent.getServletContext();
 		Context context = new Context();
@@ -203,14 +207,12 @@ public class Context extends AbstractContext {
 		context.scheduleWeight = Config.currentNode().getApplication().scheduleWeight(context.clazz);
 		context.sslEnable = Config.currentNode().getApplication().getSslEnable();
 		context.initDatas();
+		context.threadFactory = new ThreadFactory(context);
 		servletContext.setAttribute(context.getClass().getName(), context);
 		context.initialized = true;
-		/* 20190927新注册机制 */
-		// registApplication(context);
 		return context;
 	}
 
-	/* 20190927新注册机制 */
 	public void regist() throws Exception {
 		Application application = new Application();
 		application.setClassName(this.clazz().getName());

+ 3 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/AbstractActionApplication.java

@@ -5,13 +5,14 @@ import java.util.Set;
 
 import javax.ws.rs.core.Application;
 
-import com.x.base.core.project.jaxrs.sysresource.SysResourceAction;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
 
 import com.x.base.core.project.jaxrs.cache.CacheAction;
 import com.x.base.core.project.jaxrs.echo.EchoAction;
 import com.x.base.core.project.jaxrs.fireschedule.FireScheduleAction;
 import com.x.base.core.project.jaxrs.logger.LoggerAction;
+import com.x.base.core.project.jaxrs.sysresource.SysResourceAction;
+import com.x.base.core.project.jaxrs.thread.ThreadAction;
 
 public abstract class AbstractActionApplication extends Application {
 	protected Set<Object> singletons = new HashSet<>();
@@ -23,6 +24,7 @@ public abstract class AbstractActionApplication extends Application {
 		classes.add(LoggerAction.class);
 		classes.add(FireScheduleAction.class);
 		classes.add(SysResourceAction.class);
+		classes.add(ThreadAction.class);
 		// providers
 		classes.add(MessageBodyReaderImpl.class);
 		classes.add(MultiPartFeature.class);

+ 8 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/ThreadJaxrsFilter.java

@@ -0,0 +1,8 @@
+package com.x.base.core.project.jaxrs;
+
+import javax.servlet.annotation.WebFilter;
+
+@WebFilter(urlPatterns = { "/jaxrs/thread/*" }, asyncSupported = true)
+public class ThreadJaxrsFilter extends CipherManagerJaxrsFilter {
+
+}

+ 2 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/WrapBoolean.java

@@ -5,6 +5,8 @@ import com.x.base.core.project.gson.GsonPropertyObject;
 
 public class WrapBoolean extends GsonPropertyObject {
 
+	private static final long serialVersionUID = 19308077998975323L;
+
 	@FieldDescribe("布尔值.")
 	private Boolean value;
 

+ 28 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionAlive.java

@@ -0,0 +1,28 @@
+package com.x.base.core.project.jaxrs.thread;
+
+import javax.servlet.ServletContext;
+
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WrapString;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+class ActionAlive extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionAlive.class);
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, ServletContext servletContext, String name)
+			throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		com.x.base.core.project.Context ctx = com.x.base.core.project.Context.fromServletContext(servletContext);
+		Wo wo = new Wo();
+		wo.setValue(ctx.threadFactory().aliveLocal(name));
+		result.setData(wo);
+		return result;
+	}
+
+	public static class Wo extends WrapString {
+	}
+
+}

+ 23 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionParameter.java

@@ -0,0 +1,23 @@
+package com.x.base.core.project.jaxrs.thread;
+
+import javax.servlet.ServletContext;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+class ActionParameter extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionParameter.class);
+
+	ActionResult<JsonElement> execute(EffectivePerson effectivePerson, ServletContext servletContext, String name)
+			throws Exception {
+		ActionResult<JsonElement> result = new ActionResult<>();
+		com.x.base.core.project.Context ctx = com.x.base.core.project.Context.fromServletContext(servletContext);
+		result.setData(gson.toJsonTree(ctx.threadFactory().parameterLocal(name)));
+		return result;
+	}
+
+}

+ 23 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ActionStop.java

@@ -0,0 +1,23 @@
+package com.x.base.core.project.jaxrs.thread;
+
+import javax.servlet.ServletContext;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+class ActionStop extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionStop.class);
+
+	ActionResult<JsonElement> execute(EffectivePerson effectivePerson, ServletContext servletContext, String name)
+			throws Exception {
+		ActionResult<JsonElement> result = new ActionResult<>();
+		com.x.base.core.project.Context ctx = com.x.base.core.project.Context.fromServletContext(servletContext);
+		result.setData(gson.toJsonTree(ctx.threadFactory().stop(name)));
+		return result;
+	}
+
+}

+ 7 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/BaseAction.java

@@ -0,0 +1,7 @@
+package com.x.base.core.project.jaxrs.thread;
+
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+
+abstract class BaseAction extends StandardJaxrsAction {
+
+}

+ 75 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/thread/ThreadAction.java

@@ -0,0 +1,75 @@
+package com.x.base.core.project.jaxrs.thread;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+@Path("thread")
+@JaxrsDescribe("线程接口")
+public class ThreadAction extends StandardJaxrsAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ThreadAction.class);
+
+	@JaxrsMethodDescribe(value = "是否运行中.", action = ActionAlive.class)
+	@GET
+	@Path("alive/{name}")
+	public void alive(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@Context ServletContext servletContext, @PathParam("name") String name) {
+		ActionResult<ActionAlive.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionAlive().execute(effectivePerson, servletContext, name);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "获取参数.", action = ActionParameter.class)
+	@GET
+	@Path("parameter/{name}")
+	public void parameter(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@Context ServletContext servletContext, @PathParam("name") String name) {
+		ActionResult<JsonElement> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionParameter().execute(effectivePerson, servletContext, name);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "停止运行.", action = ActionStop.class)
+	@GET
+	@Path("stop/{name}")
+	public void stop(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@Context ServletContext servletContext, @PathParam("name") String name) {
+		ActionResult<JsonElement> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionStop().execute(effectivePerson, servletContext, name);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+}

+ 14 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/thread/ParameterRunnable.java

@@ -0,0 +1,14 @@
+package com.x.base.core.project.thread;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+public abstract class ParameterRunnable implements Runnable {
+
+	public Map<Object, Object> parameter;
+
+	public ParameterRunnable() {
+		parameter = new TreeMap<>();
+	}
+
+}

+ 251 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/thread/ThreadFactory.java

@@ -0,0 +1,251 @@
+package com.x.base.core.project.thread;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import com.x.base.core.project.AbstractContext;
+import com.x.base.core.project.Application;
+import com.x.base.core.project.Applications;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.jaxrs.WrapString;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.StringTools;
+
+public class ThreadFactory {
+
+	private static Logger logger = LoggerFactory.getLogger(ThreadFactory.class);
+
+	private Applications applications;
+
+	private AbstractContext context;
+
+	private Type parameterType;
+
+	private static final String THREAD = "thread";
+	private static final String STOP = "stop";
+	private static final String ALIVE = "alive";
+	private static final String PARAMETER = "parameter";
+
+	public ThreadFactory(AbstractContext context) throws Exception {
+		this.context = context;
+		this.applications = context.applications();
+		this.group = new ThreadGroup("ThreadFactoryGroup-" + StringTools.uniqueToken());
+		this.parameterType = new TypeToken<Map<Object, Object>>() {
+		}.getType();
+	}
+
+	private static final String TARGET = "target";
+	private ThreadGroup group;
+
+	public void start(ParameterRunnable runnable, String name) {
+		Thread thread = new Thread(group, runnable::run, name);
+		thread.start();
+	}
+
+	public String alive(String name) throws Exception {
+		List<Application> list = applications.get(context.clazz());
+		List<String> values = new CopyOnWriteArrayList<>();
+		CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
+			if (list.stream().anyMatch(o -> {
+				try {
+					return StringUtils.equals(o.getNode(), Config.node());
+				} catch (Exception e) {
+					logger.error(e);
+				}
+				return false;
+			})) {
+				values.add(aliveLocal(name));
+			}
+		}), CompletableFuture.runAsync(() -> values.addAll(aliveRemote(name, list))));
+		return values.stream().filter(StringUtils::isNotBlank).collect(Collectors.joining(","));
+	}
+
+	public String aliveLocal(String name) {
+		try {
+			return find(name).isPresent() ? Config.node() : null;
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return null;
+	}
+
+	private List<String> aliveRemote(String name, List<Application> list) {
+		final List<String> values = new CopyOnWriteArrayList<>();
+		list.stream().filter(o -> {
+			try {
+				return !StringUtils.equals(o.getNode(), Config.node());
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return false;
+		}).map(o -> CompletableFuture.supplyAsync(() -> {
+			try {
+				return applications.getQuery(o, Applications.joinQueryUri(THREAD, ALIVE, name))
+						.getData(WrapString.class).getValue();
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return false;
+		})).forEach(f -> {
+			try {
+				values.add(Objects.toString(f.get()));
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		});
+		return values;
+	}
+
+	public Optional<Map<Object, Object>> parameter(String name) throws Exception {
+		List<Application> list = applications.get(context.clazz());
+		final List<Map<Object, Object>> values = new CopyOnWriteArrayList<>();
+		CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
+			if (list.stream().anyMatch(o -> {
+				try {
+					return StringUtils.equals(o.getNode(), Config.node());
+				} catch (Exception e) {
+					logger.error(e);
+				}
+				return false;
+			})) {
+				values.add(this.parameterLocal(name));
+			}
+		}), CompletableFuture.runAsync(() -> values.add(parameterRemote(name, list))));
+		return values.stream().filter(Objects::nonNull).findFirst();
+	}
+
+	public Map<Object, Object> parameterLocal(String name) {
+		Optional<Thread> optional = find(name);
+		if (optional.isPresent()) {
+			try {
+				Object r = FieldUtils.readField(optional.get(), TARGET, true);
+				if (r instanceof ParameterRunnable) {
+					return ((ParameterRunnable) r).parameter;
+				}
+			} catch (IllegalAccessException e) {
+				logger.error(e);
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Map<Object, Object> parameterRemote(String name, List<Application> list) {
+		final List<Map<Object, Object>> values = new CopyOnWriteArrayList<>();
+		list.stream().filter(o -> {
+			try {
+				return !StringUtils.equals(o.getNode(), Config.node());
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return false;
+		}).map(o -> CompletableFuture.supplyAsync(() -> {
+			try {
+				JsonElement jsonElement = applications.getQuery(o, Applications.joinQueryUri(THREAD, PARAMETER, name))
+						.getData();
+				return XGsonBuilder.instance().fromJson(jsonElement, parameterType);
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return null;
+		})).forEach(o -> {
+			try {
+				if (null != o.get()) {
+					values.add((Map<Object, Object>) o.get());
+				}
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		});
+		return values.stream().filter(Objects::nonNull).findFirst().orElse(null);
+	}
+
+	public Optional<Map<Object, Object>> stop(String name) throws Exception {
+		List<Application> list = applications.get(context.clazz());
+		final List<Map<Object, Object>> values = new CopyOnWriteArrayList<>();
+		CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
+			if (list.stream().anyMatch(o -> {
+				try {
+					return StringUtils.equals(o.getNode(), Config.node());
+				} catch (Exception e) {
+					logger.error(e);
+				}
+				return false;
+			})) {
+				try {
+					values.add(stopLocal(name));
+				} catch (Exception e) {
+					logger.error(e);
+				}
+			}
+		}), CompletableFuture.runAsync(() -> values.add(stopRemote(name, list))));
+		return values.stream().filter(Objects::nonNull).findFirst();
+	}
+
+	public Map<Object, Object> stopLocal(String name) {
+		Optional<Thread> optional = find(name);
+		if (optional.isPresent()) {
+			try {
+				Object r = FieldUtils.readField(optional.get(), TARGET, true);
+				optional.get().interrupt();
+				if (r instanceof ParameterRunnable) {
+					return ((ParameterRunnable) r).parameter;
+				}
+			} catch (IllegalAccessException e) {
+				logger.error(e);
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Map<Object, Object> stopRemote(String name, List<Application> list) {
+		final List<Map<Object, Object>> values = new CopyOnWriteArrayList<>();
+		list.stream().filter(o -> {
+			try {
+				return !StringUtils.equals(o.getNode(), Config.node());
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return false;
+		}).map(o -> CompletableFuture.supplyAsync(() -> {
+			try {
+				JsonElement jsonElement = applications.getQuery(o, Applications.joinQueryUri(THREAD, STOP, name))
+						.getData();
+				return XGsonBuilder.instance().fromJson(jsonElement, parameterType);
+			} catch (Exception e) {
+				logger.error(e);
+			}
+			return null;
+		})).forEach(o -> {
+			try {
+				if (null != o.get()) {
+					values.add((Map<Object, Object>) o.get());
+				}
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		});
+		return values.stream().filter(Objects::nonNull).findFirst().orElse(null);
+	}
+
+	private Optional<Thread> find(String name) {
+		return Thread.getAllStackTraces().keySet().stream()
+				.filter(o -> Objects.equals(o.getThreadGroup(), group) && StringUtils.equals(name, o.getName()))
+				.findFirst();
+	}
+
+}

+ 7 - 4
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionListLike.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.group;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -19,6 +20,8 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -27,8 +30,6 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Group;
 import com.x.organization.core.entity.Group_;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLike extends BaseAction {
 
@@ -104,7 +105,7 @@ class ActionListLike extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Group.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Group> cq = cb.createQuery(Group.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Group> root = cq.from(Group.class);
 		Predicate p = cb.like(cb.lower(root.get(Group_.name)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR);
 		p = cb.or(p, cb.like(cb.lower(root.get(Group_.unique)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR));
@@ -114,7 +115,9 @@ class ActionListLike extends BaseAction {
 		if (ListTools.isNotEmpty(groupIds)) {
 			p = cb.and(p, root.get(Group_.id).in(groupIds));
 		}
-		List<Group> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Group_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Group> os = business.entityManagerContainer().list(Group.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.group().sort(wos);
 		return wos;

+ 9 - 6
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionListLikePinyin.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.group;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -19,6 +20,8 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -27,8 +30,6 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Group;
 import com.x.organization.core.entity.Group_;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLikePinyin extends BaseAction {
 
@@ -37,8 +38,8 @@ class ActionListLikePinyin extends BaseAction {
 			ActionResult<List<Wo>> result = new ActionResult<>();
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			Business business = new Business(emc);
-			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(),
-					StringUtils.join(wi.getGroupList(), ","), StringUtils.join(wi.getRoleList(), ","));
+			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(), StringUtils.join(wi.getGroupList(), ","),
+					StringUtils.join(wi.getRoleList(), ","));
 			Optional<?> optional = CacheManager.get(business.cache(), cacheKey);
 			if (optional.isPresent()) {
 				result.setData((List<Wo>) optional.get());
@@ -105,14 +106,16 @@ class ActionListLikePinyin extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Group.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Group> cq = cb.createQuery(Group.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Group> root = cq.from(Group.class);
 		Predicate p = cb.like(root.get(Group_.pinyin), str + "%");
 		p = cb.or(p, cb.like(root.get(Group_.pinyinInitial), str + "%"));
 		if (ListTools.isNotEmpty(groupIds)) {
 			p = cb.and(p, root.get(Group_.id).in(groupIds));
 		}
-		List<Group> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Group_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Group> os = business.entityManagerContainer().list(Group.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.group().sort(wos);
 		return wos;

+ 8 - 7
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionListLike.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.identity;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -39,10 +40,8 @@ class ActionListLike extends BaseAction {
 			ActionResult<List<Wo>> result = new ActionResult<>();
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			Business business = new Business(emc);
-			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(),
-					StringUtils.join(wi.getUnitList(), ","),
-					StringUtils.join(wi.getUnitDutyList(), ","),
-					StringUtils.join(wi.getGroupList(), ","));
+			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(), StringUtils.join(wi.getUnitList(), ","),
+					StringUtils.join(wi.getUnitDutyList(), ","), StringUtils.join(wi.getGroupList(), ","));
 			Optional<?> optional = CacheManager.get(business.cache(), cacheKey);
 			if (optional.isPresent()) {
 				result.setData((List<Wo>) optional.get());
@@ -116,7 +115,7 @@ class ActionListLike extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Identity.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Identity> cq = cb.createQuery(Identity.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Identity> root = cq.from(Identity.class);
 		Predicate p = cb.conjunction();
 		p = cb.and(p, cb.or(cb.like(cb.lower(root.get(Identity_.name)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR),
@@ -142,10 +141,12 @@ class ActionListLike extends BaseAction {
 			List<String> identityIds = business.expendGroupToIdentity(wi.getGroupList());
 			set.addAll(identityIds);
 		}
-		if(!set.isEmpty()){
+		if (!set.isEmpty()) {
 			p = cb.and(p, root.get(Identity_.id).in(set.asList()));
 		}
-		List<Identity> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Identity_.id)).where(p)).getResultList().stream()
+				.distinct().collect(Collectors.toList());
+		List<Identity> os = business.entityManagerContainer().list(Identity.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.identity().sort(wos);
 		return wos;

+ 10 - 9
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionListLikePinyin.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.identity;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -20,6 +21,8 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -29,8 +32,6 @@ import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Identity;
 import com.x.organization.core.entity.Identity_;
 import com.x.organization.core.entity.UnitDuty;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLikePinyin extends BaseAction {
 
@@ -39,10 +40,8 @@ class ActionListLikePinyin extends BaseAction {
 			ActionResult<List<Wo>> result = new ActionResult<>();
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			Business business = new Business(emc);
-			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(),
-					StringUtils.join(wi.getUnitList(), ","),
-					StringUtils.join(wi.getUnitDutyList(), ","),
-					StringUtils.join(wi.getGroupList(), ","));
+			CacheKey cacheKey = new CacheKey(this.getClass(), wi.getKey(), StringUtils.join(wi.getUnitList(), ","),
+					StringUtils.join(wi.getUnitDutyList(), ","), StringUtils.join(wi.getGroupList(), ","));
 			Optional<?> optional = CacheManager.get(business.cache(), cacheKey);
 			if (optional.isPresent()) {
 				result.setData((List<Wo>) optional.get());
@@ -117,7 +116,7 @@ class ActionListLikePinyin extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Identity.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Identity> cq = cb.createQuery(Identity.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Identity> root = cq.from(Identity.class);
 		Predicate p = cb.conjunction();
 		p = cb.and(p, cb.or(cb.like(cb.lower(root.get(Identity_.pinyin)), str + "%", StringTools.SQL_ESCAPE_CHAR),
@@ -140,10 +139,12 @@ class ActionListLikePinyin extends BaseAction {
 			List<String> identityIds = business.expendGroupToIdentity(wi.getGroupList());
 			set.addAll(identityIds);
 		}
-		if(!set.isEmpty()){
+		if (!set.isEmpty()) {
 			p = cb.and(p, root.get(Identity_.id).in(set.asList()));
 		}
-		List<Identity> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Identity_.id)).where(p)).getResultList().stream()
+				.distinct().collect(Collectors.toList());
+		List<Identity> os = business.entityManagerContainer().list(Identity.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.identity().sort(wos);
 		return wos;

+ 9 - 6
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/person/ActionListLike.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.person;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -36,8 +37,8 @@ class ActionListLike extends BaseAction {
 			ActionResult<List<Wo>> result = new ActionResult<>();
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			Business business = new Business(emc);
-			CacheKey cacheKey = new CacheKey(this.getClass(), effectivePerson.getDistinguishedName(),
-					wi.getKey(), StringUtils.join(wi.getGroupList(), ","), StringUtils.join(wi.getRoleList(), ","));
+			CacheKey cacheKey = new CacheKey(this.getClass(), effectivePerson.getDistinguishedName(), wi.getKey(),
+					StringUtils.join(wi.getGroupList(), ","), StringUtils.join(wi.getRoleList(), ","));
 			Optional<?> optional = CacheManager.get(business.cache(), cacheKey);
 			if (optional.isPresent()) {
 				result.setData((List<Wo>) optional.get());
@@ -96,7 +97,7 @@ class ActionListLike extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Person.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Person> cq = cb.createQuery(Person.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Person> root = cq.from(Person.class);
 		Predicate p = cb.like(cb.lower(root.get(Person_.name)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR);
 		p = cb.or(p, cb.like(cb.lower(root.get(Person_.unique)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR));
@@ -106,13 +107,15 @@ class ActionListLike extends BaseAction {
 		p = cb.or(p, cb.like(cb.lower(root.get(Person_.distinguishedName)), str + "%", StringTools.SQL_ESCAPE_CHAR));
 		if (ListTools.isNotEmpty(personIds)) {
 			p = cb.and(p, root.get(Person_.id).in(personIds));
-		}else{
-			if(ListTools.isNotEmpty(wi.getGroupList(), wi.getRoleList())) {
+		} else {
+			if (ListTools.isNotEmpty(wi.getGroupList(), wi.getRoleList())) {
 				return wos;
 			}
 		}
 		p = cb.and(p, business.personPredicateWithTopUnit(effectivePesron));
-		List<Person> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Person_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Person> os = business.entityManagerContainer().list(Person.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.person().sort(wos);
 		return wos;

+ 11 - 8
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/person/ActionListLikePinyin.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.person;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -18,6 +19,8 @@ import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -26,8 +29,6 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Person;
 import com.x.organization.core.entity.Person_;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLikePinyin extends BaseAction {
 
@@ -36,8 +37,8 @@ class ActionListLikePinyin extends BaseAction {
 			ActionResult<List<Wo>> result = new ActionResult<>();
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			Business business = new Business(emc);
-			CacheKey cacheKey = new CacheKey(this.getClass(), effectivePerson.getDistinguishedName(),
-					wi.getKey(), StringUtils.join(wi.getGroupList(), ","), StringUtils.join(wi.getRoleList(), ","));
+			CacheKey cacheKey = new CacheKey(this.getClass(), effectivePerson.getDistinguishedName(), wi.getKey(),
+					StringUtils.join(wi.getGroupList(), ","), StringUtils.join(wi.getRoleList(), ","));
 			Optional<?> optional = CacheManager.get(business.cache(), cacheKey);
 			if (optional.isPresent()) {
 				result.setData((List<Wo>) optional.get());
@@ -96,19 +97,21 @@ class ActionListLikePinyin extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Person.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Person> cq = cb.createQuery(Person.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Person> root = cq.from(Person.class);
 		Predicate p = cb.like(root.get(Person_.pinyin), str + "%");
 		p = cb.or(p, cb.like(root.get(Person_.pinyinInitial), str + "%"));
 		if (ListTools.isNotEmpty(personIds)) {
 			p = cb.and(p, root.get(Person_.id).in(personIds));
-		}else{
-			if(ListTools.isNotEmpty(wi.getGroupList(), wi.getRoleList())) {
+		} else {
+			if (ListTools.isNotEmpty(wi.getGroupList(), wi.getRoleList())) {
 				return wos;
 			}
 		}
 		p = cb.and(p, business.personPredicateWithTopUnit(effectivePerson));
-		List<Person> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Person_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Person> os = business.entityManagerContainer().list(Person.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.person().sort(wos);
 		return wos;

+ 8 - 5
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/role/ActionListLike.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.role;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -19,6 +20,9 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -27,9 +31,6 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Role;
 import com.x.organization.core.entity.Role_;
-import com.x.base.core.project.cache.Cache;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLike extends BaseAction {
 
@@ -107,7 +108,7 @@ class ActionListLike extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Role.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Role> cq = cb.createQuery(Role.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Role> root = cq.from(Role.class);
 		Predicate p = cb.like(cb.lower(root.get(Role_.name)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR);
 		p = cb.or(p, cb.like(cb.lower(root.get(Role_.pinyin)), str + "%", StringTools.SQL_ESCAPE_CHAR));
@@ -116,7 +117,9 @@ class ActionListLike extends BaseAction {
 		if (ListTools.isNotEmpty(roleIds)) {
 			p = cb.and(p, root.get(Role_.id).in(roleIds));
 		}
-		List<Role> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Role_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Role> os = business.entityManagerContainer().list(Role.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.role().sort(wos);
 		return wos;

+ 8 - 5
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/role/ActionListLikePinyin.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.role;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -19,6 +20,9 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.Cache;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.project.cache.CacheManager;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -27,9 +31,6 @@ import com.x.base.core.project.tools.StringTools;
 import com.x.organization.assemble.control.Business;
 import com.x.organization.core.entity.Role;
 import com.x.organization.core.entity.Role_;
-import com.x.base.core.project.cache.Cache;
-import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.project.cache.CacheManager;
 
 class ActionListLikePinyin extends BaseAction {
 
@@ -106,14 +107,16 @@ class ActionListLikePinyin extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Role.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Role> cq = cb.createQuery(Role.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Role> root = cq.from(Role.class);
 		Predicate p = cb.like(root.get(Role_.pinyin), str + "%");
 		p = cb.or(p, cb.like(root.get(Role_.pinyinInitial), str + "%"));
 		if (ListTools.isNotEmpty(roleIds)) {
 			p = cb.and(p, root.get(Role_.id).in(roleIds));
 		}
-		List<Role> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Role_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Role> os = business.entityManagerContainer().list(Role.class, ids);
 		wos = Wo.copier.copy(os);
 		wos = business.role().sort(wos);
 		return wos;

+ 5 - 3
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/unit/ActionListLike.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.unit;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -142,7 +143,7 @@ class ActionListLike extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Unit.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Unit> cq = cb.createQuery(Unit.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Unit> root = cq.from(Unit.class);
 		Predicate p = cb.like(cb.lower(root.get(Unit_.name)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR);
 		p = cb.or(p, cb.like(cb.lower(root.get(Unit_.unique)), "%" + str + "%", StringTools.SQL_ESCAPE_CHAR));
@@ -156,8 +157,9 @@ class ActionListLike extends BaseAction {
 		if (StringUtils.isNotEmpty(wi.getType())) {
 			p = cb.and(p, cb.isMember(wi.getType(), root.get(Unit_.typeList)));
 		}
-		cq.select(root).where(p);
-		List<Unit> os = em.createQuery(cq).getResultList();
+		cq.select(root.get(Unit_.id)).where(p);
+		List<String> ids = em.createQuery(cq).getResultList().stream().distinct().collect(Collectors.toList());
+		List<Unit> os = business.entityManagerContainer().list(Unit.class, ids);
 		wos = Wo.copier.copy(os);
 		for (Wo wo : wos) {
 			wo.setWoSupNestedUnitList(Wo.copier.copy(business.unit().listSupNestedObject(wo)));

+ 5 - 2
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/unit/ActionListLikePinyin.java

@@ -3,6 +3,7 @@ package com.x.organization.assemble.control.jaxrs.unit;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -142,7 +143,7 @@ class ActionListLikePinyin extends BaseAction {
 		String str = StringUtils.lowerCase(StringTools.escapeSqlLikeKey(wi.getKey()));
 		EntityManager em = business.entityManagerContainer().get(Unit.class);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<Unit> cq = cb.createQuery(Unit.class);
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Unit> root = cq.from(Unit.class);
 		Predicate p = cb.like(root.get(Unit_.pinyin), str + "%");
 		p = cb.or(p, cb.like(root.get(Unit_.pinyinInitial), str + "%"));
@@ -152,7 +153,9 @@ class ActionListLikePinyin extends BaseAction {
 		if (StringUtils.isNotEmpty(wi.getType())) {
 			p = cb.and(p, cb.isMember(wi.getType(), root.get(Unit_.typeList)));
 		}
-		List<Unit> os = em.createQuery(cq.select(root).where(p)).getResultList();
+		List<String> ids = em.createQuery(cq.select(root.get(Unit_.id)).where(p)).getResultList().stream().distinct()
+				.collect(Collectors.toList());
+		List<Unit> os = business.entityManagerContainer().list(Unit.class, ids);
 		wos = Wo.copier.copy(os);
 		for (Wo wo : wos) {
 			wo.setWoSupNestedUnitList(Wo.copier.copy(business.unit().listSupNestedObject(wo)));