- 11、【优化】执行器任务Bean扫描逻辑优化,完善懒加载Bean检测及过滤机制;

- 12、【新增】执行器新增“任务扫描排除路径”配置项(xxl.job.executor.excludedpackage),任务扫描时忽略指定包路径下的Bean;支持配置多个包路径、逗号分隔;
pull/72/head
xuxueli 2 months ago
parent e9362be210
commit 7117b2a002

@ -981,7 +981,7 @@ xxl.job.executor.port=9999
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; ### 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=30 xxl.job.executor.logretentiondays=30
### 任务扫描排除路径任务扫描时忽略指定包路径下的Bean支持配置多个包路径、逗号分隔; ### 任务扫描排除路径 [选填] 任务扫描时忽略指定包路径下的Bean支持配置包路径前缀多个逗号分隔;
xxl.job.executor.excludedpackage=org.springframework,spring xxl.job.executor.excludedpackage=org.springframework,spring
``` ```

@ -183,11 +183,11 @@ public class XxlJobExecutor {
public static IJobHandler loadJobHandler(String name){ public static IJobHandler loadJobHandler(String name){
return jobHandlerRepository.get(name); return jobHandlerRepository.get(name);
} }
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){ public static IJobHandler registryJobHandler(String name, IJobHandler jobHandler){
logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler); logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
return jobHandlerRepository.put(name, jobHandler); return jobHandlerRepository.put(name, jobHandler);
} }
protected void registJobHandler(XxlJob xxlJob, Object bean, Method executeMethod){ protected void registryJobHandler(XxlJob xxlJob, Object bean, Method executeMethod){
if (xxlJob == null) { if (xxlJob == null) {
return; return;
} }
@ -237,7 +237,7 @@ public class XxlJobExecutor {
} }
// registry jobhandler // registry jobhandler
registJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod)); registryJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod));
} }

@ -2,14 +2,12 @@ package com.xxl.job.core.executor.impl;
import com.xxl.job.core.executor.XxlJobExecutor; import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.handler.impl.MethodJobHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
@ -65,7 +63,7 @@ public class XxlJobSimpleExecutor extends XxlJobExecutor {
for (Method executeMethod : methods) { for (Method executeMethod : methods) {
XxlJob xxlJob = executeMethod.getAnnotation(XxlJob.class); XxlJob xxlJob = executeMethod.getAnnotation(XxlJob.class);
// registry // registry
registJobHandler(xxlJob, bean, executeMethod); registryJobHandler(xxlJob, bean, executeMethod);
} }
} }

@ -43,12 +43,14 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
// ---------------------- start / stop ---------------------- // ---------------------- start / stop ----------------------
// start /**
* start
*/
@Override @Override
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
// init JobHandler Repository (for method) // scan JobHandler method
initJobHandlerMethodRepository(applicationContext); scanJobHandlerMethod(applicationContext);
// refresh GlueFactory // refresh GlueFactory
GlueFactory.refreshInstance(1); GlueFactory.refreshInstance(1);
@ -61,45 +63,27 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
} }
} }
// destroy /**
* stop
*/
@Override @Override
public void destroy() { public void destroy() {
super.destroy(); super.destroy();
} }
/**
* check bean if excluded
*
* @param excludedPackageList excludedPackageList
* @param beanClassName beanClassName
* @return true if excluded
*/
private boolean isExcluded(List<String> excludedPackageList, String beanClassName) {
if (excludedPackageList == null || excludedPackageList.isEmpty() || beanClassName==null) {
return false;
}
for (String excludedPackage : excludedPackageList) {
if (beanClassName.startsWith(excludedPackage)) {
return true;
}
}
return false;
}
/** /**
* init job handler from method * init job handler from method
* *
* @param applicationContext applicationContext * @param applicationContext applicationContext
*/ */
private void initJobHandlerMethodRepository(ApplicationContext applicationContext) { private void scanJobHandlerMethod(ApplicationContext applicationContext) {
// valid // valid
if (applicationContext == null) { if (applicationContext == null) {
return; return;
} }
// build excluded package list // 1、build excluded-package list
List<String> excludedPackageList = new ArrayList<>(); List<String> excludedPackageList = new ArrayList<>();
if (excludedPackage != null) { if (excludedPackage != null) {
for (String excludedPackage : excludedPackage.split(",")) { for (String excludedPackage : excludedPackage.split(",")) {
@ -109,39 +93,50 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
} }
} }
// init job handler from method // 2、scan bean form jobhandler
String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, false); // allowEagerInit=false, avoid early initialization String[] beanNames = applicationContext.getBeanNamesForType(Object.class, false, false); // allowEagerInit=false, avoid early initialization
for (String beanDefinitionName : beanDefinitionNames) { for (String beanName : beanNames) {
// analyse BeanDefinition /**
* 2.1skip by BeanDefinition:
* - skip excluded-package bean
* - skip lazy-init bean
*/
if (applicationContext instanceof BeanDefinitionRegistry beanDefinitionRegistry) { if (applicationContext instanceof BeanDefinitionRegistry beanDefinitionRegistry) {
// get BeanDefinition // get BeanDefinition
if (!beanDefinitionRegistry.containsBeanDefinition(beanDefinitionName)) { if (!beanDefinitionRegistry.containsBeanDefinition(beanName)) {
continue; continue;
} }
BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(beanDefinitionName); BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(beanName);
// skip excluded bean // skip excluded-package bean
String beanClassName = beanDefinition.getBeanClassName(); String beanClassName = beanDefinition.getBeanClassName();
if (isExcluded(excludedPackageList, beanClassName)) { if (isExcluded(excludedPackageList, beanClassName)) {
logger.debug(">>>>>>>>>>> xxl-job bean-definition scan, skip excluded-package beanDefinitionName:{}, beanClassName:{}", beanDefinitionName, beanClassName); logger.debug(">>>>>>>>>>> xxl-job bean-definition scan, skip excluded-package beanName:{}, beanClassName:{}", beanName, beanClassName);
continue; continue;
} }
// skip lazy bean // skip lazy-init bean
if (beanDefinition.isLazyInit()) { if (beanDefinition.isLazyInit()) {
logger.debug(">>>>>>>>>>> xxl-job bean-definition scan, skip lazy-init beanDefinitionName:{}", beanDefinitionName); logger.debug(">>>>>>>>>>> xxl-job bean-definition scan, skip lazy-init beanName:{}", beanName);
continue; continue;
} }
} }
// load bean /**
Object bean = applicationContext.getBean(beanDefinitionName); * 2.2skip by BeanDefinition Class
* - skip beanClass is null
* - skip method annotation(@XxlJob) is null
*/
Class<?> beanClass = applicationContext.getType(beanName, false);
if (beanClass == null) {
logger.debug(">>>>>>>>>>> xxl-job bean-definition scan, skip beanClass-null beanName:{}", beanName);
continue;
}
// filter method // filter method
Map<Method, XxlJob> annotatedMethods = null; // referred to org.springframework.context.event.EventListenerMethodProcessor.processBean Map<Method, XxlJob> annotatedMethods = null;
try { try {
annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(), annotatedMethods = MethodIntrospector.selectMethods(beanClass,
new MethodIntrospector.MetadataLookup<XxlJob>() { new MethodIntrospector.MetadataLookup<XxlJob>() {
@Override @Override
public XxlJob inspect(Method method) { public XxlJob inspect(Method method) {
@ -149,23 +144,51 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
} }
}); });
} catch (Throwable ex) { } catch (Throwable ex) {
logger.error("xxl-job method-jobhandler resolve error for bean[" + beanDefinitionName + "].", ex); logger.error(">>>>>>>>>>> xxl-job method-jobhandler resolve error for bean[" + beanName + "].", ex);
} }
if (annotatedMethods==null || annotatedMethods.isEmpty()) { if (annotatedMethods==null || annotatedMethods.isEmpty()) {
continue; continue;
} }
// generate and regist method job handler // 2.3、scan + registry Jobhandler
for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) { Object jobBean = applicationContext.getBean(beanName);
Method executeMethod = methodXxlJobEntry.getKey(); for (Map.Entry<Method, XxlJob> jobMethodEntry : annotatedMethods.entrySet()) {
XxlJob xxlJob = methodXxlJobEntry.getValue(); Method jobMethod = jobMethodEntry.getKey();
XxlJob xxlJob = jobMethodEntry.getValue();
// regist // regist
registJobHandler(xxlJob, bean, executeMethod); registryJobHandler(xxlJob, jobBean, jobMethod);
} }
} }
} }
/**
* check bean if excluded
*
* @param excludedPackageList excludedPackageList
* @param beanClassName beanClassName
* @return true if excluded
*/
private boolean isExcluded(List<String> excludedPackageList, String beanClassName) {
// excludedPackageList is empty, no excluded
if (excludedPackageList == null || excludedPackageList.isEmpty()) {
return false;
}
// beanClassName is null, no excluded
if (beanClassName == null) {
return false;
}
// excludedPackageList match, excluded (not scan)
for (String excludedPackage : excludedPackageList) {
if (beanClassName.startsWith(excludedPackage)) {
return true;
}
}
return false;
}
// ---------------------- applicationContext ---------------------- // ---------------------- applicationContext ----------------------
private static ApplicationContext applicationContext; private static ApplicationContext applicationContext;

Loading…
Cancel
Save