| 
                         下面我会举例来说明我是如何进行断点追踪的,以spring-boot-2.0.3之quartz集成,不是你想的那样哦!和  spring-boot-2.0.3之quartz集成,数据源问题,源码探究  为背景来讲,需要搞清楚两个点:springboot是如何向quartz注入数据源的,quartz是如何操作数据库的 
springboot向quartz注入数据源 
QuartzAutoConfiguration是springboot自动配置quartz的入口 
将quartz的配置属性设置给SchedulerFactoryBean;将数据源设置给SchedulerFactoryBean:如果有@QuartzDataSource修饰的数据源,则将@QuartzDataSource修饰的数据源设置给SchedulerFactoryBean,否则将应用的数据源(druid数据源)设置给SchedulerFactoryBean,显然我们的应用中没有@QuartzDataSource修饰的数据源,那么SchedulerFactoryBean中的数据源就是应用的数据源;将事务管理器设置给SchedulerFactoryBean。SchedulerFactoryBean,负责创建和配置quartz  Scheduler,并将其注册到spring容器中。SchedulerFactoryBean实现InitializingBean的afterPropertiesSet方法,里面有可以设置数据源的过程 
可以看到通过org.quartz.jobStore.dataSource设置的dsName(值为quartzDs)最后会被替换成springTxDataSource.加scheduler实例名(我们的应用中是:springTxDataSource.quartzScheduler)。springboot会注册两个ConnectionProvider给quartz:一个dsName叫springTxDataSource.quartzScheduler,有事务;一个dsName叫springNonTxDataSource.quartzScheduler,没事务。 
quartz如何操作数据库 
我们通过停止定时任务来跟下quartz对数据库的操作 
发现quartz用如下方式获取connection 
- conn = DBConnectionManager.getInstance().getConnection(getDataSource()); 
 
  
那么我们的job中就可以按如下方式操作数据库了 
- package com.lee.quartz.job; 
 - import org.quartz.JobExecutionContext; 
 - import org.quartz.JobExecutionException; 
 - import org.quartz.utils.DBConnectionManager; 
 - import org.springframework.scheduling.quartz.LocalDataSourceJobStore; 
 - import org.springframework.scheduling.quartz.QuartzJobBean; 
 - import java.sql.Connection; 
 - import java.sql.PreparedStatement; 
 - import java.sql.SQLException; 
 - public class FetchDataJob extends QuartzJobBean { 
 -  // private String dataSourceName = "quartzDs"; // 用此会找不到 
 -  // private String dataSourceName = "springNonTxDataSource.quartzScheduler"; // 不支持事务 
 -  // private String dataSourceName = "springTxDataSource.quartzScheduler"; // 支持事务 
 -  private final String insertSql = "INSERT INTO tbl_sys_user(name, age) VALUES(?,?) "; 
 -  private String schedulerInstanceName = "quartzScheduler"; // 可通过jobDataMap注入进来 
 -  @Override 
 -  protected void executeInternal(JobExecutionContext context) throws JobExecutionException { 
 -  String dsName = LocalDataSourceJobStore.NON_TX_DATA_SOURCE_PREFIX 
 -  + schedulerInstanceName; // 不支持事务 
 -  //String dsName = LocalDataSourceJobStore.TX_DATA_SOURCE_PREFIX + schedulerInstanceName; // 支持事务 
 -  try { 
 -  Connection connection = DBConnectionManager.getInstance().getConnection(dsName); 
 -  PreparedStatement ps = connection.prepareStatement(insertSql); 
 -  ps.setString(1, "张三"); 
 -  ps.setInt(2, 25); 
 -  ps.executeUpdate(); 
 -  ps.close(); 
 -  connection.close(); // 将连接归还给连接池 
 -  System.out.println("插入成功"); 
 -  } catch (SQLException e) { 
 -  e.printStackTrace(); 
 -  } 
 -  } 
 -  public void setSchedulerInstanceName(String schedulerInstanceName) { 
 -  this.schedulerInstanceName = schedulerInstanceName; 
 -  } 
 - } 
 
  
明确我们的目的,找到合适的切入点,进入断点调试追踪也就容易了。 
任我说的天花乱坠,你仍无动于衷,那也只是我一厢情愿,只有局中人才能体会到其中的奥妙! 
总结与感悟                         (编辑:91站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |