服务主要启动是初始化XxlJobSpringExecutor这个bean对象,该对象定义了执行器xxlJobSpringExecutor的相关配置,如注册中心地址,服务提供地址,以及授权token等。该对象类图如下,
XxlJobSpringExecutor执行器继承XxlJobExecutor并实现Spring的ApplicationContextAware等类,对该bean进行了增强。主要核心类为XxlJobExecutor。
因为继承SmartInitializingSingleton,所以bean初始化完成之后会执行afterSingletonsInstantiated方法,该类主要为initJobHandlerMethodRepository这个方法,用于扫描xxl-job注解,进行任务加载和管理
|
@Override
public void afterSingletonsInstantiated() {
// 扫描xxl-job注解,进行任务加载和管理
initJobHandlerMethodRepository(applicationContext);
// refresh GlueFactory
GlueFactory.refreshInstance(1);
// super start
try {
super.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
initJobHandlerMethodRepository方法主要如下
该方法主要是通过获取Spring管理的容器bean,然后扫描带有xxljob注解的方法,将他们保存在jobHandlerRepository对象中
|
if (applicationContext == null) {
return;
}
// 扫描Spring管理的bean
String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = applicationContext.getBean(beanDefinitionName);
Map<Method, XxlJob> annotatedMethods = null; // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
try {
annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
new MethodIntrospector.MetadataLookup<XxlJob>() {
@Override
public XxlJob inspect(Method method) {
// 获取注解为XxlJob的方法,并保存在annotatedMethods
return AnnotatedElementUtils.findMergedAnnotation(method, XxlJob.class);
}
});
} catch (Throwable ex) {
logger.error(“xxl-job method-jobhandler resolve error for bean[” + beanDefinitionName + “].”, ex);
}
if (annotatedMethods==null || annotatedMethods.isEmpty()) {
continue;
}
//获取方法属性,并存储在jobHandlerRepository对象中
for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {
Method method = methodXxlJobEntry.getKey();
XxlJob xxlJob = methodXxlJobEntry.getValue();
if (xxlJob == null) {
continue;
}
String name = xxlJob.value();
if (name.trim().length() == 0) {
throw new RuntimeException(“xxl-job method-jobhandler name invalid, for[” + bean.getClass() + “#” + method.getName() + “] .”);
}
if (loadJobHandler(name) != null) {
throw new RuntimeException(“xxl-job jobhandler[” + name + “] naming conflicts.”);
}
// execute method
if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
throw new RuntimeException(“xxl-job method-jobhandler param-classtype invalid, for[” + bean.getClass() + “#” + method.getName() + "] , " +
“The correct method format like " public ReturnT<String> execute(String param) " .”);
}
if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
throw new RuntimeException(“xxl-job method-jobhandler return-classtype invalid, for[” + bean.getClass() + “#” + method.getName() + "] , " +
“The correct method format like " public ReturnT<String> execute(String param) " .”);
}
method.setAccessible(true);
// init and destory
Method initMethod = null;
Method destroyMethod = null;
if (xxlJob.init().trim().length() > 0) {
try {
initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
initMethod.setAccessible(tru