spring2.5
- 格式:ppt
- 大小:1.28 MB
- 文档页数:182


123132131312321d3sa1d31d3as1f3as21 spring2.0和spring2.5 及以上版本的jar 包区别 spring jar 包详解 spring jar 包详解 spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了 spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。
除了spring.jar文件,Spring还包括有其它13个独立的jar包,各自包含着对应的 Spring组件,用户可以根据自己的需要来选择组合自己的jar包,而不必引入整个spring.jar的所有类文件。
(1 spring-core.jar 这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
(2 spring-beans.jar 这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring- beans.jar文件就可以了。
(3 spring-aop.jar 这个jar文件包含在应用中使用Spring的AOP特性时所需的类。
使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。
(4 spring-context.jar 这个jar文件为 Spring核心提供了大量扩展。
可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI所需的全部类,UI方面的用来与模板(Templating)引擎如 Velocity、FreeMarker、JasperReports集成的类,以及校验Validation方面的相关类。
SpringBoot2.2.5整...展开全文前言:该博客主要是记录自己学习的过程,方便以后查看,当然也希望能够帮到大家。
由于工作上的需要,初步了解Quartz后进行使用。
完整代码地址在结尾!!第一步,在pom.xml文件中加入依赖,如下<!-- Quartz --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>第二步,自定义JobFactory类注意:我注入了一个自定义的JobFactory ,然后把它设置为SchedulerFactoryBean的JobFactory。
让其在具体job类实例化时使用spring的api来进行依赖注入,目的是因为我在具体的job中需要注入一些spring的bean。
import org.quartz.spi.TriggerFiredBundle;importorg.springframework.beans.factory.config.AutowireCapableBean Factory;importorg.springframework.scheduling.quartz.AdaptableJobFactory;import ponent;/*** @version 1.0* @author jinhaoxun* @date 2018-05-09* @description Quartz创建JobFactory实例*/@Componentpublic class JobFactory extends AdaptableJobFactory {/*** AutowireCapableBeanFactory接口是BeanFactory的子类* 可以连接和填充那些生命周期不被Spring管理的已存在的bean 实例*/private AutowireCapableBeanFactory factory;/*** @author jinhaoxun* @description 构造器* @param factory*/public JobFactory(AutowireCapableBeanFactory factory) {this.factory = factory;}/*** @author jinhaoxun* @description 创建Job实例* @param bundle* @return Object*/@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object job = super.createJobInstance(bundle);// 实例化对象factory.autowireBean(job);// 进行注入(Spring管理该Bean)return job;//返回对象}}第三步,自定义QuartzConfig配置文件import lombok.extern.slf4j.Slf4j;import org.quartz.Scheduler;import org.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.quartz.SchedulerFactoryBean;/*** @version 1.0* @author jinhaoxun* @date 2018-05-09* @description Quartz配置*/@Slf4j@Configurationpublic class QuartzConfig {private JobFactory jobFactory;/*** @author jinhaoxun* @description 构造器* @param jobFactory*/public QuartzConfig(JobFactory jobFactory){this.jobFactory = jobFactory;}/*** @author jinhaoxun* @description 配置SchedulerFactoryBean,将一个方法产生为Bean并交给Spring容器管理* @return SchedulerFactoryBean*/@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {("开始注入定时任务调度器工厂...");SchedulerFactoryBean factory = new SchedulerFactoryBean();// Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期factory.setJobFactory(jobFactory);// 设置自定义Job Factory,用于Spring管理Job bean("注入定时任务调度器工厂成功!");return factory;}@Bean(name = "scheduler")public Scheduler scheduler() {return schedulerFactoryBean().getScheduler();}}第四步,新增任务请求实体类AddSimpleJobReq,AddCronJobReq,DeleteJobReq,如下AddSimpleJobReqimport lombok.Data;import java.util.Date;import java.util.HashMap;import java.util.Map;/*** @Description: 新增Simple定时任务请求实体类* @Author: jinhaoxun* @Date: 2020/1/15 11:20* @Version: 1.0.0*/@Datapublic class AddSimpleJobReq {private String jobClass;private Date date;private Map<String, String> params = new HashMap<>();}AddCronJobReqimport lombok.Data;import java.util.HashMap;import java.util.Map;/*** @Description: 新增Cron定时任务请求实体类* @Author: jinhaoxun* @Date: 2020/1/15 11:20* @Version: 1.0.0*/@Datapublic class AddCronJobReq {private String jobName;private String jobGroupName;private String triggerName;private String triggerGroupName;private String jobClass;private String date;private Map<String, String> params = new HashMap<>();}DeleteJobReqimport lombok.Data;/*** @Description: 删除定时任务请求实体类* @Author: jinhaoxun* @Date: 2020/1/15 11:20* @Version: 1.0.0*/@Datapublic class DeleteJobReq {private String jobName;private String jobGroupName;private String triggerName;private String triggerGroupName;}第五步,自定义QuartzManager类,用于操作定时任务import com.jinhaoxun.quartz.entity.request.AddCronJobReq;importcom.jinhaoxun.quartz.entity.request.AddSimpleJobReq;import com.jinhaoxun.quartz.entity.request.DeleteJobReq;import lombok.extern.slf4j.Slf4j;import org.quartz.*;import org.springframework.stereotype.Service;import static org.quartz.DateBuilder.futureDate;/*** @Description: Quartz管理操作类* @Author: jinhaoxun* @Date: 2020/1/15 11:20* @Version: 1.0.0*/@Slf4j@Servicepublic class QuartzManager {private Scheduler scheduler;/*** @author jinhaoxun* @description 构造器* @param scheduler 调度器*/public QuartzManager(Scheduler scheduler){this.scheduler = scheduler;}/*** quartz任务类包路径*/private static String jobUri = "com.jinhaoxun.quartz.job.";/*** @author jinhaoxun* @description 添加一个Simple定时任务,只执行一次的定时任务* @param addSimpleJobReq 参数对象* @param taskId 任务ID,不能同名* @throws RuntimeException*/@SuppressWarnings({ "unchecked", "rawtypes" })public void addSimpleJob(AddSimpleJobReq addSimpleJobReq, String taskId) throws Exception {String jobUrl = jobUri + addSimpleJobReq.getJobClass();try {Class<? extends Job> aClass = (Class<? extends Job>) Class.forName(jobUrl).newInstance().getClass();// 任务名,任务组,任务执行类JobDetail job = JobBuilder.newJob(aClass).withIdentity(taskId,"JobGroup").build();//增加任务ID参数addSimpleJobReq.getParams().put("taskId",taskId);// 添加任务参数job.getJobDataMap().putAll(addSimpleJobReq.getParams());// 转换为时间差,秒单位int time = (int) (addSimpleJobReq.getDate().getTime() - System.currentTimeMillis()) / 1000;SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(taskId, taskId + "TiggerGroup").startAt(futureDate(time, DateBuilder.IntervalUnit.SECOND)) .build();// 调度容器设置JobDetail和Triggerscheduler.scheduleJob(job, trigger);if (!scheduler.isShutdown()) {// 启动scheduler.start();}} catch (Exception e) {("Quartz新增任务失败");}}/*** @author jinhaoxun* @description 添加一个Cron定时任务,循环不断执行的定时任务* @param addCronJobReq 参数对象* @throws Exception*/@SuppressWarnings({ "unchecked", "rawtypes" })public void addCronJob(AddCronJobReq addCronJobReq) throws Exception {String jobUrl = jobUri + addCronJobReq.getJobClass();try {Class<? extends Job> aClass = (Class<? extends Job>) Class.forName(jobUrl).newInstance().getClass();// 任务名,任务组,任务执行类JobDetail job = JobBuilder.newJob(aClass).withIdentity(addCronJobReq.getJobN ame(),addCronJobReq.getJobGroupName()).build();// 添加任务参数job.getJobDataMap().putAll(addCronJobReq.getParams());// 创建触发器CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()// 触发器名,触发器组.withIdentity(addCronJobReq.getTriggerName(),addCronJobReq.getTriggerGroupName())// 触发器时间设定.withSchedule(CronScheduleBuilder.cronSchedule(addCronJ obReq.getDate())).build();// 调度容器设置JobDetail和Triggerscheduler.scheduleJob(job, trigger);if (!scheduler.isShutdown()) {// 启动scheduler.start();}} catch (Exception e) {("Quartz新增任务失败");}}/*** @author jinhaoxun* @description 修改一个任务的触发时间* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param cron 时间设置,参考quartz说明文档* @throws Exception*/public void modifyJobTime(String triggerName, String triggerGroupName, String cron) throws Exception {try {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(cron)) {// 触发器TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 触发器名,触发器组triggerBuilder.withIdentity(triggerName, triggerGroupName);triggerBuilder.startNow();// 触发器时间设定triggerBuilder.withSchedule(CronScheduleBuilder.cronSched ule(cron));// 创建Trigger对象trigger = (CronTrigger) triggerBuilder.build();// 方式一:修改一个任务的触发时间scheduler.rescheduleJob(triggerKey, trigger);}} catch (Exception e) {("Quartz修改任务失败");}}/*** @author jinhaoxun* @description 移除一个任务* @param deleteJobReq 参数对象* @throws Exception*/public void removeJob(DeleteJobReq deleteJobReq) throws Exception {try {TriggerKey triggerKey = TriggerKey.triggerKey(deleteJobReq.getTriggerName(), deleteJobReq.getTriggerGroupName());// 停止触发器scheduler.pauseTrigger(triggerKey);// 移除触发器scheduler.unscheduleJob(triggerKey);// 删除任务scheduler.deleteJob(JobKey.jobKey(deleteJobReq.getJobNa me(), deleteJobReq.getJobGroupName()));} catch (Exception e) {("Quartz删除改任务失败");}}/*** @author jinhaoxun* @description 获取任务是否存在* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @return Boolean 返回操作结果* 获取任务是否存在* STATE_BLOCKED 4 阻塞* STATE_COMPLETE 2 完成* STATE_ERROR 3 错误* STATE_NONE -1 不存在* STATE_NORMAL 0 正常* STATE_PAUSED 1 暂停* @throws Exception*/public Boolean notExists(String triggerName, String triggerGroupName) throws Exception {try {if(scheduler.getTriggerState(TriggerKey.triggerKey(triggerName, triggerGroupName)) == Trigger.TriggerState.NORMAL){ return true;}} catch (Exception e) {("Quartz获取任务是否存在失败");}return false;}/*** @author jinhaoxun* @description 关闭调度器* @throws RuntimeException*/public void shutdown() throws Exception {try {if(scheduler.isStarted()){scheduler.shutdown(true);}} catch (Exception e) {("Quartz关闭调度器失败");}}}第六步,新增自定义任务类型,将要做的操作放到该类的execute方法中,主要该类的路径,要放到上面配置的com.jinhaoxun.quartz.job包里面import lombok.extern.slf4j.Slf4j;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;/*** @Description: Job测试类* @Author: jinhaoxun* @Date: 2020/1/15 11:20* @Version: 1.0.0*/@Slf4jpublic class JobT est implements Job {/*** @author jinhaoxun* @description 重写任务内容* @param jobExecutionContext 设置的key* @throws*/@Overridepublic void execute(JobExecutionContextjobExecutionContext) {//获取参数JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();String id = dataMap.getString("id");String name = dataMap.getString("name");try {("执行任务{},{}",id,name);} catch (Exception e) {("Quartz执行失败");}}}第七步,编写单元测试类,QuartzApplicationTests,并进行测试,使用方法基本都有注释import com.luoyu.quartz.entity.request.AddCronJobReq;import com.luoyu.quartz.entity.request.AddSimpleJobReq;import com.luoyu.quartz.entity.request.DeleteJobReq;import com.luoyu.quartz.manager.QuartzManager;import lombok.extern.slf4j.Slf4j;import org.junit.jupiter.api.AfterEach;import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootT est;import java.util.Calendar;import java.util.Date;import java.util.HashMap;import java.util.Map;@Slf4j// 获取启动类,加载配置,确定装载 Spring 程序的装载方法,它回去寻找主配置启动类(被 @SpringBootApplication 注解的)@SpringBootT estclass QuartzApplicationTests {@Autowiredprivate QuartzManager quartzManager;@Testvoid addSimpleJobTest() throws Exception {Map<String, String> params = new HashMap<>();params.put("id","测试id");params.put("name","测试name");Calendar beforeTime = Calendar.getInstance();// 5 秒之后的时间beforeTime.add(Calendar.SECOND, 5);Date beforeDate = beforeTime.getTime();AddSimpleJobReq addSimpleJobReq = new AddSimpleJobReq();addSimpleJobReq.setDate(beforeDate);addSimpleJobReq.setJobClass("JobTest");addSimpleJobReq.setParams(params);quartzManager.addSimpleJob(addSimpleJobReq, "123");// 让主线程睡眠60秒Thread.currentThread().sleep(60000);}@Testvoid addCronJobT est() throws Exception {Map<String, String> params = new HashMap<>();params.put("id","测试id");params.put("name","测试name");AddCronJobReq addCronJobReq = new AddCronJobReq();//每 5 秒执行一次addCronJobReq.setDate("0/5 * * * * ?");addCronJobReq.setJobClass("JobTest");addCronJobReq.setJobGroupName("JobGroupName");addCronJobReq.setJobName("JobName");addCronJobReq.setParams(params);addCronJobReq.setTriggerGroupName("triggerGroupName ");addCronJobReq.setTriggerName("triggerName");quartzManager.addCronJob(addCronJobReq);// 让主线程睡眠60秒Thread.currentThread().sleep(60000);}@Testvoid removeJobTest() throws Exception {Map<String, String> params = new HashMap<>();params.put("id","测试id");params.put("name","测试name");Calendar beforeTime = Calendar.getInstance();// 5 秒之后的时间beforeTime.add(Calendar.SECOND, 5);Date beforeDate = beforeTime.getTime();AddSimpleJobReq addSimpleJobReq = new AddSimpleJobReq();addSimpleJobReq.setDate(beforeDate);addSimpleJobReq.setJobClass("JobTest");addSimpleJobReq.setParams(params);quartzManager.addSimpleJob(addSimpleJobReq, "123");DeleteJobReq deleteJobReq = new DeleteJobReq();deleteJobReq.setJobName("123");deleteJobReq.setJobGroupName("123JobGroup");deleteJobReq.setTriggerName("123");deleteJobReq.setTriggerGroupName("123TiggerGroup");quartzManager.removeJob(deleteJobReq);// 让主线程睡眠60秒Thread.currentThread().sleep(60000);}@Testvoid shutdownTest() throws Exception {quartzManager.shutdown();}@BeforeEachvoid testBefore(){("测试开始");}@AfterEachvoid testAfter(){("测试结束");}}完整代码地址:https:///Jinhx128/springboot-demo注:此工程包含多个module,本文所用代码均在quartz-demo 模块下后记:本次分享到此结束,本人水平有限,难免有错误或遗漏之处,望大家指正和谅解,欢迎评论留言。
SpringBoot2.5.0重新设计的spring.sql.init配置有啥⽤弃⽤内容先来纠正⼀个误区。
主要之前在版本更新介绍的时候,存在⼀些表述上的问题。
导致部分读者认为这次的更新是Datasource 本⾝初始化的调整,但其实并不是。
这次重新设计的只是对Datasource脚本初始化机制的重新设计。
先来看看这次被弃⽤部分的内容(位于org.springframework.boot.autoconfigure.jdbc.DataSourceProperties),如果你有⽤过这些配置内容,那么新配置就很容易理解了。
/*** Mode to apply when determining if DataSource initialization should be performed* using the available DDL and DML scripts.*/@Deprecatedprivate DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;/*** Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or* data-${platform}.sql).*/@Deprecatedprivate String platform = "all";/*** Schema (DDL) script resource references.*/private List<String> schema;/*** Username of the database to execute DDL scripts (if different).*/@Deprecatedprivate String schemaUsername;/*** Password of the database to execute DDL scripts (if different).*/@Deprecatedprivate String schemaPassword;/*** Data (DML) script resource references.*/@Deprecatedprivate List<String> data;/*** Username of the database to execute DML scripts (if different).*/@Deprecatedprivate String dataUsername;/*** Password of the database to execute DML scripts (if different).*/@Deprecatedprivate String dataPassword;/*** Whether to stop if an error occurs while initializing the database.*/@Deprecatedprivate boolean continueOnError = false;/*** Statement separator in SQL initialization scripts.*/@Deprecatedprivate String separator = ";";/*** SQL scripts encoding.*/@Deprecatedprivate Charset sqlScriptEncoding;对应到配置⽂件⾥的属性如下(这⾥仅列出部分,就不全部列出了,主要就是对应上⾯源码中的属性):spring.datasource.schema=spring.datasource.schema-username=spring.datasource.schema-password=...这些配置主要⽤来指定数据源初始化之后要⽤什么⽤户、去执⾏哪些脚本、遇到错误是否继续等功能。