diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java b/xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java index e5b90b7a..36b12f2f 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java @@ -113,7 +113,7 @@ public class ExecutorBizImpl implements ExecutorBiz { // valid handler if (jobHandler == null) { try { - IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource()); + IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getJobId(), triggerParam.getGlueSource()); jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime()); } catch (Exception e) { logger.error(e.getMessage(), e); diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java b/xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java index 8b9e8cd2..d6104026 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java @@ -4,6 +4,10 @@ import com.xxl.job.core.glue.impl.SpringGlueFactory; import com.xxl.job.core.handler.IJobHandler; import groovy.lang.GroovyClassLoader; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.concurrent.ConcurrentHashMap; + /** * glue factory, product class/object by name * @@ -30,6 +34,8 @@ public class GlueFactory { */ private GroovyClassLoader groovyClassLoader = new GroovyClassLoader(); + private static final ConcurrentHashMap> CLASS_CACHE = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap JOBID_MD5KEY_CACHE = new ConcurrentHashMap<>(); /** * load new instance, prototype @@ -38,9 +44,9 @@ public class GlueFactory { * @return * @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) { - Class clazz = groovyClassLoader.parseClass(codeSource); + Class clazz = getCodeSourceClass(jobId, codeSource); if (clazz != null) { Object instance = clazz.newInstance(); if (instance!=null) { @@ -66,4 +72,28 @@ public class GlueFactory { // 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); + } + } }