| 
															
																@@ -4,6 +4,10 @@ import com.xxl.job.core.glue.impl.SpringGlueFactory; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 import com.xxl.job.core.handler.IJobHandler;
 
															 | 
															
															 | 
															
																 import com.xxl.job.core.handler.IJobHandler;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 import groovy.lang.GroovyClassLoader;
 
															 | 
															
															 | 
															
																 import groovy.lang.GroovyClassLoader;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
 
															 | 
															
															 | 
															
																 
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+import java.math.BigInteger;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+import java.security.MessageDigest;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+import java.util.concurrent.ConcurrentHashMap;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 /**
 
															 | 
															
															 | 
															
																 /**
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  * glue factory, product class/object by name
 
															 | 
															
															 | 
															
																  * glue factory, product class/object by name
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  *
 
															 | 
															
															 | 
															
																  *
 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -30,6 +34,8 @@ public class GlueFactory { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	 */
 
															 | 
															
															 | 
															
																 	 */
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
 
															 | 
															
															 | 
															
																 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
 
															 | 
															
															 | 
															
																 
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	private static final ConcurrentHashMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	private static final ConcurrentHashMap<Long, String> JOBID_MD5KEY_CACHE = new ConcurrentHashMap<>();
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
 
															 | 
															
															 | 
															
																 
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	/**
 
															 | 
															
															 | 
															
																 	/**
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	 * load new instance, prototype
 
															 | 
															
															 | 
															
																 	 * load new instance, prototype
 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -38,9 +44,9 @@ public class GlueFactory { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	 * @return
 
															 | 
															
															 | 
															
																 	 * @return
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	 * @throws Exception
 
															 | 
															
															 | 
															
																 	 * @throws Exception
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	 */
 
															 | 
															
															 | 
															
																 	 */
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	public IJobHandler loadNewInstance(String codeSource) throws Exception{
 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	public IJobHandler loadNewInstance(long jobId, String codeSource) throws Exception{
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		if (codeSource!=null && codeSource.trim().length()>0) {
 
															 | 
															
															 | 
															
																 		if (codeSource!=null && codeSource.trim().length()>0) {
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			Class<?> clazz = groovyClassLoader.parseClass(codeSource);
 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			Class<?> clazz = getCodeSourceClass(jobId, codeSource);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			if (clazz != null) {
 
															 | 
															
															 | 
															
																 			if (clazz != null) {
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				Object instance = clazz.newInstance();
 
															 | 
															
															 | 
															
																 				Object instance = clazz.newInstance();
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				if (instance!=null) {
 
															 | 
															
															 | 
															
																 				if (instance!=null) {
 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -66,4 +72,28 @@ public class GlueFactory { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		// do something
 
															 | 
															
															 | 
															
																 		// do something
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	}
 
															 | 
															
															 | 
															
																 	}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
 
															 | 
															
															 | 
															
																 
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	private Class<?> getCodeSourceClass(long jobId, String codeSource){
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+		try {
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			MessageDigest md = MessageDigest.getInstance("MD5");
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			byte[] md5 = md.digest(codeSource.getBytes());
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			BigInteger no = new BigInteger(1, md5);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			String md5Str = no.toString(16);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			Class<?> clazz = CLASS_CACHE.get(md5Str);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			if(clazz == null){
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				clazz = groovyClassLoader.parseClass(codeSource);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				Class<?> preClazz = CLASS_CACHE.putIfAbsent(md5Str, clazz);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				// 如果代碼有變化則刪除之前class緩存
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				if(preClazz == null){
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					String preMd5 = JOBID_MD5KEY_CACHE.put(jobId, md5Str);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					if(preMd5 != null){
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+						CLASS_CACHE.remove(preMd5);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			return clazz;
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+		} catch (Exception e) {
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			return groovyClassLoader.parseClass(codeSource);
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+		}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	}
 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 }
 
															 | 
															
															 | 
															
																 }
 
															 |