瀏覽代碼

Merge pull request #677 from soenter/master

许雪里 6 年之前
父節點
當前提交
3e9fe7baa4
沒有帳戶連結到提交者的電子郵件

+ 1 - 1
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java 查看文件

113
             // valid handler
113
             // valid handler
114
             if (jobHandler == null) {
114
             if (jobHandler == null) {
115
                 try {
115
                 try {
116
-                    IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource());
116
+                    IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getJobId(), triggerParam.getGlueSource());
117
                     jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime());
117
                     jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime());
118
                 } catch (Exception e) {
118
                 } catch (Exception e) {
119
                     logger.error(e.getMessage(), e);
119
                     logger.error(e.getMessage(), e);

+ 32 - 2
xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java 查看文件

4
 import com.xxl.job.core.handler.IJobHandler;
4
 import com.xxl.job.core.handler.IJobHandler;
5
 import groovy.lang.GroovyClassLoader;
5
 import groovy.lang.GroovyClassLoader;
6
 
6
 
7
+import java.math.BigInteger;
8
+import java.security.MessageDigest;
9
+import java.util.concurrent.ConcurrentHashMap;
10
+
7
 /**
11
 /**
8
  * glue factory, product class/object by name
12
  * glue factory, product class/object by name
9
  *
13
  *
30
 	 */
34
 	 */
31
 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
35
 	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
32
 
36
 
37
+	private static final ConcurrentHashMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();
38
+	private static final ConcurrentHashMap<Long, String> JOBID_MD5KEY_CACHE = new ConcurrentHashMap<>();
33
 
39
 
34
 	/**
40
 	/**
35
 	 * load new instance, prototype
41
 	 * load new instance, prototype
38
 	 * @return
44
 	 * @return
39
 	 * @throws Exception
45
 	 * @throws Exception
40
 	 */
46
 	 */
41
-	public IJobHandler loadNewInstance(String codeSource) throws Exception{
47
+	public IJobHandler loadNewInstance(long jobId, String codeSource) throws Exception{
42
 		if (codeSource!=null && codeSource.trim().length()>0) {
48
 		if (codeSource!=null && codeSource.trim().length()>0) {
43
-			Class<?> clazz = groovyClassLoader.parseClass(codeSource);
49
+			Class<?> clazz = getCodeSourceClass(jobId, codeSource);
44
 			if (clazz != null) {
50
 			if (clazz != null) {
45
 				Object instance = clazz.newInstance();
51
 				Object instance = clazz.newInstance();
46
 				if (instance!=null) {
52
 				if (instance!=null) {
66
 		// do something
72
 		// do something
67
 	}
73
 	}
68
 
74
 
75
+	private Class<?> getCodeSourceClass(long jobId, String codeSource){
76
+		try {
77
+			MessageDigest md = MessageDigest.getInstance("MD5");
78
+			byte[] md5 = md.digest(codeSource.getBytes());
79
+			BigInteger no = new BigInteger(1, md5);
80
+			String md5Str = no.toString(16);
81
+			Class<?> clazz = CLASS_CACHE.get(md5Str);
82
+			if(clazz == null){
83
+				clazz = groovyClassLoader.parseClass(codeSource);
84
+				Class<?> preClazz = CLASS_CACHE.putIfAbsent(md5Str, clazz);
85
+
86
+				// 如果代碼有變化則刪除之前class緩存
87
+				if(preClazz == null){
88
+					String preMd5 = JOBID_MD5KEY_CACHE.put(jobId, md5Str);
89
+					if(preMd5 != null){
90
+						CLASS_CACHE.remove(preMd5);
91
+					}
92
+				}
93
+			}
94
+			return clazz;
95
+		} catch (Exception e) {
96
+			return groovyClassLoader.parseClass(codeSource);
97
+		}
98
+	}
69
 }
99
 }