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

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

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

@ -183,11 +183,11 @@ public class XxlJobExecutor {
public static IJobHandler loadJobHandler(String 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);
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) {
return;
}
@ -237,7 +237,7 @@ public class XxlJobExecutor {
}
// 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.handler.annotation.XxlJob;
import com.xxl.job.core.handler.impl.MethodJobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
@ -65,7 +63,7 @@ public class XxlJobSimpleExecutor extends XxlJobExecutor {
for (Method executeMethod : methods) {
XxlJob xxlJob = executeMethod.getAnnotation(XxlJob.class);
// registry
registJobHandler(xxlJob, bean, executeMethod);
registryJobHandler(xxlJob, bean, executeMethod);
}
}

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

Loading…
Cancel
Save