xxl-job客户端如何接入spring boot,按xxl-job官方给出来的demo,需要以下几个过程
- 首先是配置
- 接着配置扫描地址,把对应的jobHandler加载到spring容器中
- 配置XxlJobSpringExecutor,接着启动项目即可
1、======================================================================
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin,http://192.168.1.168:1888/xxl-job-admin
### xxl-job executor address
xxl.job.executor.appname=app-job-executor
xxl.job.executor.ip=
xxl.job.executor.port=9998
### xxl-job, access token
xxl.job.accessToken=
### xxl-job log path
xxl.job.executor.logpath=D:/xxl-job
### xxl-job log retention days
xxl.job.executor.logretentiondays=-1
2、=========================================================================
@Configuration
@ComponentScan(basePackages = "com.xxl.job.executor.service.jobhandler")
3、=========================================================================
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppName(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
ok,那我们分析一下主要的init流程与接收调度中心调度请求的流程
1、首先定位到XxlJobSpringExecutor的initMethod,start()
@Override
public void start() throws Exception {
//初始化jobHandler
initJobHandlerRepository(applicationContext);
// refresh GlueFactory
GlueFactory.refreshInstance(1);
// super start
super.start();
}
private void initJobHandlerRepository(ApplicationContext applicationContext){
if (applicationContext == null) {
return;
}
// 从spring中拿到JobHandler注解的bean map
Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class);
if (serviceBeanMap!=null && serviceBeanMap.size()>0) {
for (Object serviceBean : serviceBeanMap.values()) {
//判断是否IJobHandler
if (serviceBean instanceof IJobHandler){
String name = serviceBean.getClass().getAnnotation(JobHandler.class).value();
IJobHandler handler = (IJobHandler) serviceBean;
if (loadJobHandler(name) != null) {
throw new RuntimeException("xxl-job jobhandler naming conflicts.");
}
//拿到JobHandler注解的名字,以及IJobHandler放入jobHandlerRepository中
registJobHandler(name, handler);
}
}
}
}
// ---------------------- job handler repository ----------------------
private static ConcurrentHashMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
return jobHandlerRepository.put(name, jobHandler);
}
2、调用父类XxlJobExecutor的start()方法,首先我们看initAdminBizList();
private static List<AdminBiz> adminBizList;
//拿到我们刚才设置的adminAddresses列表(xxl.job.admin.addresses)
private void initAdminBizList(String adminAddresses, String accessToken) throws Exception {
if (adminAddresses!=null && adminAddresses.trim().length()>0) {
for (String address: adminAddresses.trim().split(",")) {
if (address!=null && address.trim().length()>0) {
//addressUrl地址:http://127.0.0.1:8080/xxl-job-admin/api
String addressUrl = address.concat(AdminBiz.MAPPING);
//通过XxlRpcReferenceBean#getObject()设置动态代理,主要用来请求和处理rpc信息,这里使用的是JETTY,JettyServer和JettyClient去处理,还支持mima,netty等的扩展
AdminBiz adminBiz = (AdminBiz) new XxlRpcReferenceBean(NetEnum.JETTY, Serializer.SerializeEnum.HESSIAN.getSerializer(), CallType.SYNC,
AdminBiz.class, null, 10000, addressUrl, accessToken, null).getObject();
if (adminBizList == null) {
adminBizList = new ArrayList<AdminBiz>();
}
//放入adminBizList中
adminBizList.add(adminBiz);
}
}
}
}
//XxlRpcReferenceBean#getObject()
public Object getObject() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{this.iface}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//....代码太多,略过
}
}
});
}
3、启动日志清理守护线程
//感兴趣可以自己看
JobLogFileCleanThread.getInstance().start(logRetentionDays);
4、启动触发器回调守护线程
TriggerCallbackThread.