加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

杂谈篇之我是怎么读源码的,授之以渔

发布时间:2019-02-22 19:15:10 所属栏目:建站 来源:liujh
导读:读源码的经历 刚参加工作那会,没想过去读源码,更没想过去改框架的源码;总想着别人的框架应该是完美的、万能的,应该不需要改;另外即使我改了源码,怎么样让我的改动生效了? 项目中引用的不还是没改的jar包吗。回想起来觉得那时候的想法确实挺...... 工作

下面我会举例来说明我是如何进行断点追踪的,以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

  1. conn = DBConnectionManager.getInstance().getConnection(getDataSource()); 

那么我们的job中就可以按如下方式操作数据库了

  1. package com.lee.quartz.job; 
  2. import org.quartz.JobExecutionContext; 
  3. import org.quartz.JobExecutionException; 
  4. import org.quartz.utils.DBConnectionManager; 
  5. import org.springframework.scheduling.quartz.LocalDataSourceJobStore; 
  6. import org.springframework.scheduling.quartz.QuartzJobBean; 
  7. import java.sql.Connection; 
  8. import java.sql.PreparedStatement; 
  9. import java.sql.SQLException; 
  10. public class FetchDataJob extends QuartzJobBean { 
  11.  // private String dataSourceName = "quartzDs"; // 用此会找不到 
  12.  // private String dataSourceName = "springNonTxDataSource.quartzScheduler"; // 不支持事务 
  13.  // private String dataSourceName = "springTxDataSource.quartzScheduler"; // 支持事务 
  14.  private final String insertSql = "INSERT INTO tbl_sys_user(name, age) VALUES(?,?) "; 
  15.  private String schedulerInstanceName = "quartzScheduler"; // 可通过jobDataMap注入进来 
  16.  @Override 
  17.  protected void executeInternal(JobExecutionContext context) throws JobExecutionException { 
  18.  String dsName = LocalDataSourceJobStore.NON_TX_DATA_SOURCE_PREFIX 
  19.  + schedulerInstanceName; // 不支持事务 
  20.  //String dsName = LocalDataSourceJobStore.TX_DATA_SOURCE_PREFIX + schedulerInstanceName; // 支持事务 
  21.  try { 
  22.  Connection connection = DBConnectionManager.getInstance().getConnection(dsName); 
  23.  PreparedStatement ps = connection.prepareStatement(insertSql); 
  24.  ps.setString(1, "张三"); 
  25.  ps.setInt(2, 25); 
  26.  ps.executeUpdate(); 
  27.  ps.close(); 
  28.  connection.close(); // 将连接归还给连接池 
  29.  System.out.println("插入成功"); 
  30.  } catch (SQLException e) { 
  31.  e.printStackTrace(); 
  32.  } 
  33.  } 
  34.  public void setSchedulerInstanceName(String schedulerInstanceName) { 
  35.  this.schedulerInstanceName = schedulerInstanceName; 
  36.  } 

明确我们的目的,找到合适的切入点,进入断点调试追踪也就容易了。

任我说的天花乱坠,你仍无动于衷,那也只是我一厢情愿,只有局中人才能体会到其中的奥妙!

总结与感悟

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读