|
|
@ -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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|