springboot和quartz整合實現動態定時任務(持久化單節點)

  Quartz是一個完全由java編寫的開源作業調度框架,為在Java應用程序中進行作業調度提供了簡單卻強大的機制,它支持定時任務持久化到數據庫,從而避免了重啟服務器時任務丟失,支持分布式多節點,大大的提高了單節點定時任務的容錯性。springboot在2.0版本以前沒有對quartz做自動配置,因此需要我們自己去手動配置,網上找了許多資料,但是大都不能完全滿足自己的需要,因此自己整合了一下方便以后參考(copy),整合代碼基于springboot1.5.9和quartz2.3.0,過程如下:

  1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>powerx.io</groupId><artifactId>springboot-quartz</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>springboot-quartz</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><druid.version>1.1.5</druid.version><quartz.version>2.3.0</quartz.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!--quartz相關依賴--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>${quartz.version}</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>${quartz.version}</version></dependency><!--定時任務需要依賴context模塊--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

  2、整合配置類

  采用jobDetail使用Spring Ioc托管方式來完成整合,我們可以在定時任務實例中使用Spring注入注解完成業務邏輯處理,代碼如下

package com.example.demo.config;import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;import javax.sql.DataSource;@Configuration
@EnableScheduling
public class QuartzConfiguration {/*** 繼承org.springframework.scheduling.quartz.SpringBeanJobFactory* 實現任務實例化方式*/public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implementsApplicationContextAware {private transient AutowireCapableBeanFactory beanFactory;@Overridepublic void setApplicationContext(final ApplicationContext context) {beanFactory = context.getAutowireCapableBeanFactory();}/*** 將job實例交給spring ioc托管* 我們在job實例實現類內可以直接使用spring注入的調用被spring ioc管理的實例** @param bundle* @return* @throws Exception*/@Overrideprotected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {final Object job = super.createJobInstance(bundle);/*** 將job實例交付給spring ioc*/beanFactory.autowireBean(job);return job;}}/*** 配置任務工廠實例** @return*/@Beanpublic JobFactory jobFactory() {/*** 采用自定義任務工廠 整合spring實例來完成構建任務*/AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();return jobFactory;}/*** 配置任務調度器* 使用項目數據源作為quartz數據源** @param jobFactory 自定義配置任務工廠* @param dataSource 數據源實例* @return* @throws Exception*/@Bean(destroyMethod = "destroy", autowire = Autowire.NO)public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();//將spring管理job自定義工廠交由調度器維護
        schedulerFactoryBean.setJobFactory(jobFactory);//設置覆蓋已存在的任務schedulerFactoryBean.setOverwriteExistingJobs(true);//項目啟動完成后,等待2秒后開始執行調度器初始化schedulerFactoryBean.setStartupDelay(2);//設置調度器自動運行schedulerFactoryBean.setAutoStartup(true);//設置數據源,使用與項目統一數據源
        schedulerFactoryBean.setDataSource(dataSource);//設置上下文spring bean nameschedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");//設置配置文件位置schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));return schedulerFactoryBean;}
}

  AutowiringSpringBeanJobFactory:可以看到上面配置類中,AutowiringSpringBeanJobFactory我們繼承了SpringBeanJobFactory類,并且通過實現ApplicationContextAware接口獲取ApplicationContext設置方法,通過外部實例化時設置ApplicationContext實例對象,在createJobInstance方法內,我們采用AutowireCapableBeanFactory來托管SpringBeanJobFactory類中createJobInstance方法返回的定時任務實例,這樣我們就可以在定時任務類內使用Spring Ioc相關的注解進行注入業務邏輯實例了。

  JobFactory:自定義任務工廠

  SchedulerFactoryBean:使用項目內部數據源的方式來設置調度器的jobSotre,官方quartz有兩種持久化的配置方案。

  第一種:采用quartz.properties配置文件配置獨立的定時任務數據源,可以與使用項目的數據庫完全獨立。
  第二種:采用與創建項目統一個數據源,定時任務持久化相關的表與業務邏輯在同一個數據庫內。

  可以根據實際的項目需求采取不同的方案,我采用了第二種方案,在上面配置類中可以看到方法schedulerFactoryBean內自動注入了JobFactory實例,也就是我們自定義的AutowiringSpringBeanJobFactory任務工廠實例,另外一個參數就是DataSource,在我們引入spring-boot-starter-jdbc依賴后會根據application.yml文件內的數據源相關配置自動實例化DataSource實例,這里直接注入是沒有問題的。我們通過調用SchedulerFactoryBean對象的setConfigLocation方法來設置quartz定時任務框架的基本配置,配置文件所在位置:resources/quartz.properties => classpath:/quartz.properties下。

  quartz.properties內容如下:

org.quartz.scheduler.instanceName = schedulerFactoryBeanorg.quartz.scheduler.instanceId = AUTOorg.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.tablePrefix = QRTZ_org.quartz.jobStore.useProperties = falseorg.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount = 10org.quartz.threadPool.threadPriority = 5

  在上面配置中org.quartz.jobStore.classorg.quartz.jobStore.driverDelegateClass是定時任務持久化的關鍵配置,配置了數據庫持久化定時任務以及采用MySQL數據庫進行連接,當然你也可以連接別的數據庫org.quartz.jobStore.tablePrefix屬性配置了定時任務數據表的前綴,在quartz官方提供的創建表SQL腳本默認就是qrtz_,我們需要解壓quartz2.3.0的jar,在quartz-2.2.3/docs/dbTables下找到tables_mysql_innodb.sql,然后在mysql客戶端執行來創建相應的表。

  3、動態定時任務demo

  QuartzService.java

package com.example.demo.service;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;import javax.annotation.PostConstruct;import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;@Service
public class QuartzService {@Autowiredprivate Scheduler scheduler;@PostConstructpublic void startScheduler() {try {scheduler.start();} catch (SchedulerException e) {e.printStackTrace();}}/*** 增加一個job* * @param jobClass*            任務實現類* @param jobName*            任務名稱* @param jobGroupName*            任務組名* @param jobTime*            時間表達式 (這是每隔多少秒為一次任務)* @param jobTimes*            運行的次數 (<0:表示不限次數)*/public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,int jobTimes) {try {JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任務名稱和組構成任務key
                    .build();// 使用simpleTrigger規則Trigger trigger = null;if (jobTimes < 0) {trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime)).startNow().build();} else {trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes)).startNow().build();}scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {e.printStackTrace();}}/*** 增加一個job* * @param jobClass*            任務實現類* @param jobName*            任務名稱* @param jobGroupName*            任務組名* @param jobTime*            時間表達式 (如:0/5 * * * * ? )*/public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime) {try {// 創建jobDetail實例,綁定Job實現類// 指明job的名稱,所在組的名稱,以及綁定job類JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任務名稱和組構成任務key
                    .build();// 定義調度觸發規則// 使用cornTrigger規則Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)// 觸發器key.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND)).withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();// 把作業和觸發器注冊到任務調度中
            scheduler.scheduleJob(jobDetail, trigger);} catch (Exception e) {e.printStackTrace();}}/*** 修改 一個job的 時間表達式* * @param jobName* @param jobGroupName* @param jobTime*/public void updateJob(String jobName, String jobGroupName, String jobTime) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();// 重啟觸發器
            scheduler.rescheduleJob(triggerKey, trigger);} catch (SchedulerException e) {e.printStackTrace();}}/*** 刪除任務一個job* * @param jobName*            任務名稱* @param jobGroupName*            任務組名*/public void deleteJob(String jobName, String jobGroupName) {try {scheduler.deleteJob(new JobKey(jobName, jobGroupName));} catch (Exception e) {e.printStackTrace();}}/*** 暫停一個job* * @param jobName* @param jobGroupName*/public void pauseJob(String jobName, String jobGroupName) {try {JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);scheduler.pauseJob(jobKey);} catch (SchedulerException e) {e.printStackTrace();}}/*** 恢復一個job* * @param jobName* @param jobGroupName*/public void resumeJob(String jobName, String jobGroupName) {try {JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);scheduler.resumeJob(jobKey);} catch (SchedulerException e) {e.printStackTrace();}}/*** 立即執行一個job* * @param jobName* @param jobGroupName*/public void runAJobNow(String jobName, String jobGroupName) {try {JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);scheduler.triggerJob(jobKey);} catch (SchedulerException e) {e.printStackTrace();}}/*** 獲取所有計劃中的任務列表* * @return*/public List<Map<String, Object>> queryAllJob() {List<Map<String, Object>> jobList = null;try {GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);jobList = new ArrayList<Map<String, Object>>();for (JobKey jobKey : jobKeys) {List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);for (Trigger trigger : triggers) {Map<String, Object> map = new HashMap<>();map.put("jobName", jobKey.getName());map.put("jobGroupName", jobKey.getGroup());map.put("description", "觸發器:" + trigger.getKey());Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());map.put("jobStatus", triggerState.name());if (trigger instanceof CronTrigger) {CronTrigger cronTrigger = (CronTrigger) trigger;String cronExpression = cronTrigger.getCronExpression();map.put("jobTime", cronExpression);}jobList.add(map);}}} catch (SchedulerException e) {e.printStackTrace();}return jobList;}/*** 獲取所有正在運行的job* * @return*/public List<Map<String, Object>> queryRunJob() {List<Map<String, Object>> jobList = null;try {List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();jobList = new ArrayList<Map<String, Object>>(executingJobs.size());for (JobExecutionContext executingJob : executingJobs) {Map<String, Object> map = new HashMap<String, Object>();JobDetail jobDetail = executingJob.getJobDetail();JobKey jobKey = jobDetail.getKey();Trigger trigger = executingJob.getTrigger();map.put("jobName", jobKey.getName());map.put("jobGroupName", jobKey.getGroup());map.put("description", "觸發器:" + trigger.getKey());Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());map.put("jobStatus", triggerState.name());if (trigger instanceof CronTrigger) {CronTrigger cronTrigger = (CronTrigger) trigger;String cronExpression = cronTrigger.getCronExpression();map.put("jobTime", cronExpression);}jobList.add(map);}} catch (SchedulerException e) {e.printStackTrace();}return jobList;}}

  UserService.java

package com.example.demo.service;import org.springframework.stereotype.Service;@Service
public class UserService {public void play() {System.out.println("user id play");}public void study() {System.out.println("user id study");}
}

  TestJob1.java

package com.example.demo.job;import java.util.Date;import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;public class TestJob1 extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {System.out.println(new Date() + "    job執行");}}

  TestJob2.java

package com.example.demo.job;import java.util.Date;import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;import com.example.demo.service.UserService;
@Component
public class TestJob2 extends QuartzJobBean {//注入業務service,完成定時任務邏輯
    @Autowiredprivate UserService service;@Overrideprotected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {System.out.println(new Date() + "    job2執行");service.play();}}

  TestController.java

package com.example.demo.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.example.demo.job.TestJob1;
import com.example.demo.job.TestJob2;
import com.example.demo.service.QuartzService;@RestController
public class TestController {@Autowiredprivate QuartzService quartzService;@RequestMapping("/addjob")public void startJob(String type) {if("TestJob1".equals(type)) {quartzService.addJob(TestJob1.class, "job1", "test", "0/5 * * * * ?");}else {quartzService.addJob(TestJob2.class, "job2", "test", "0/5 * * * * ?");}}@RequestMapping("/updatejob")public void updatejob() {quartzService.updateJob("job1", "test", "0/10 * * * * ?");}@RequestMapping("/deletejob")public void deletejob() {quartzService.deleteJob("job1", "test");}@RequestMapping("/pauseJob")public void pauseJob() {quartzService.pauseJob("job1", "test");}@RequestMapping("/resumeJob")public void resumeJob() {quartzService.resumeJob("job1", "test");}@RequestMapping("/queryAllJob")public Object queryAllJob() {return quartzService.queryAllJob();}@RequestMapping("/queryRunJob")public Object queryRunJob() {return quartzService.queryRunJob();}
}

  4、application.yml

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
    username: rootpassword: rootjpa:hibernate:ddl-auto: update #ddl-auto:設為update表示每次都不會重新建表show-sql: trueapplication:name: quartz-cluster-node-first
server:port: 8081
# 打印日志
logging:level:root: INFOorg.hibernate: INFOorg.hibernate.type.descriptor.sql.BasicBinder: TRACEorg.hibernate.type.descriptor.sql.BasicExtractor: TRACEcom.springms: DEBUG

  至此,springboot整合quartz實現動態定時任務和任務持久化完畢,各功能我都測試過,符合預期,具體結果不再貼出,小伙伴們在使用時要注意springboot和quartz的版本問題,很多時候并不是代碼有問題,而是jar不匹配。springboot2.0以后,直接有了spring-boot-starter-quartz包,我們只需要把原來的jar替換掉,無需任何配置就完成了整合。

?

轉載于:https://www.cnblogs.com/hhhshct/p/9707710.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JAVA中protected的作用

類NewObject中有protected修飾的方法或者屬性&#xff0c;則&#xff1a; 同一個包中&#xff1a; 可在同一個包里的子類中實例化NewObject類獲得對象&#xff0c;然后可用該對象訪問protected修飾的方法或者屬性&#xff0c;即.操作訪問。可在同一個包里的非子類中實例化NewOb…

wsimport 不是內部或外部命令,也不是可運行的程序或批處理文件

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 今天使用wsimport生成webservice client端代碼&#xff0c;wsimport提示不是內部或外部命令&#xff0c;也不是可運行的程序或批處理文件…

靜態變量的多線程同步問題

2019獨角獸企業重金招聘Python工程師標準>>> 我們先來討論一個問題&#xff0c;一個類的靜態變量當類被多次實例化的時候&#xff0c;靜態變量是否會受影響&#xff1f;首先我們應該清楚的是靜態變量是在類被JVM classloader的時候分配內存&#xff0c;并且是分配在…

extends和implements區別

extends和implements區別 extends與implements的不同 1、在類的聲明中&#xff0c;通過關鍵字extends來創建一個類的子類。 一個類通過關鍵字implements聲明自己使用一個或者多個接口。 extends 是繼承某個類, 繼承之后可以使用父類的方法, 也可以重寫父類的方法; imple…

評論:電商巨頭們誰有勇氣曬曬“價格戰”賬單?

摘要&#xff1a;國內電商接二連三上演的“價格戰”&#xff0c;點燃了消費者的購買熱情。在筆者看來&#xff0c;如果有哪個大型電商有勇氣亮出價格戰賬單&#xff0c;那對競爭對手的刺激和打擊效果將非同一般。曬出了賬單后&#xff0c;消費者對購物場所的選擇也將一目了然&a…

The xxx collides with a package/type

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 當類和包&#xff0c;重名時&#xff0c;包會報錯誤&#xff1a;The package aaa.a collides with a type&#xff1b;類也會報警告&…

Hive 行列轉換

在京東眾多業務中&#xff0c;促銷業務充滿了復雜性和挑戰性&#xff0c;因為業務的靈活性&#xff0c;很多數據都存儲成xml和json格式數據&#xff0c;這就要求下游數據分析師們需要對其做解析后方可使用 。 在眾多操作中 &#xff0c;有一種是需要對數據做行列轉換操作。 數據…

[譯] 論 Rust 和 WebAssembly 對源碼地址索引的極限優化

原文地址&#xff1a;Oxidizing Source Maps with Rust and WebAssembly原文作者&#xff1a;Nick Fitzgerald譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;D-kylinTom Tromey 和我嘗試使用 Rust 語言進行編碼&#xff0…

Java WebService 簡單實例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 前言&#xff1a;朋友們開始以下教程前&#xff0c;請先看第五大點的注意事項&#xff0c;以避免不必要的重復操作。 一、準備工作&…

互聯網侵入手機逐鹿背后:追求流量變現能力

摘要&#xff1a;小米聯合創始人黎萬強說&#xff0c;賣出10萬臺得免速死&#xff0c;賣出百萬臺算是得到了一張正式入行的門票。小米是一家新創公司&#xff0c;黎萬強自己說&#xff0c;原本一無所有&#xff0c;作為原創品牌&#xff0c;它選擇了口碑之路&#xff0c;則必須…

java api使用ElastichSearch指南

AggregationBuilders.terms:一段時間內&#xff0c;某個字段取值的數量排名前幾的聚合 / ** param startTime 開始的時間* param endTime 結束的時間* param termAggName term過濾* param fieldName 要做count的字段* param top 返回的數量*/ RangeQueryBuilder actionPeriod …

關于JavaScript的數組隨機排序

昨天了解了一下Fisher–Yates shuffle費雪耶茲隨機置亂算法&#xff0c;現在再來看看下面這個曾經網上常見的一個寫法&#xff1a; function shuffle(arr) { arr.sort(function () { return Math.random() - 0.5; }); } 或者使用更簡潔的 ES6 的寫法&#xff1a; function shu…

通用唯一識別碼UUID

UUID是通用唯一識別碼&#xff08;Universally Unique Identifier&#xff09;的縮寫。UUID 的目的&#xff0c;是讓分布式系統中的所有元素&#xff0c;都能有唯一的辨識資訊&#xff0c;而不需要透過中央控制端來做辨識資訊的指定。如此一來&#xff0c;每個人都可以建立不與…

java內省機制 + 內省是什么 + 內省實現方式 + 和反射的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、內省是什么、實現方式&#xff1a; 內省&#xff08;Introspector&#xff09;是Java語言對Bean類屬性、事件的一種缺省處理方法。…

百度聯合長虹發布第二款云手機 售價900元以下

摘要&#xff1a;【搜狐IT消息】5月15日消息&#xff0c;百度今天宣布聯合長虹發布第二款智能手機&#xff0c;采用3.5英寸屏幕、300萬像素攝像頭&#xff0c;650MHz主頻處理器&#xff0c;零售價格在700-899元之間&#xff0c;中國聯通將為其提供話費補貼。 【搜狐IT消息】5月…

vmware workstation17環境安裝centos7

打開控制面板&#xff0c;搜索“服務”&#xff0c;啟動vmware authorize service -------解決無法開啟虛擬機問題之無法連接MKS 2.虛擬機硬盤擴展為15G------解決安裝centos7時出現的“檢查存儲配置出錯”問題 3.硬盤分區----/boot 300mb&#xff08;不能小于200mb&#xff0…

博客園中的源代碼格式顯示

昨天寫了一篇文章&#xff0c;但是在寫的時候呢&#xff0c;沒有注意&#xff0c;直接將代碼復制上去了&#xff0c;今天正好有人提醒&#xff0c;看到了格式的混亂&#xff0c;借此記錄整理一下&#xff0c;如何能直接粘貼代碼&#xff0c;而且格式&#xff08;縮進&#xff0…

static的使用

類中的靜態變量在程序運行期間&#xff0c;其內存空間對所有該類的對象實例而言是共享的&#xff0c;為了節省系統內存開銷、共享資源&#xff0c;應該對一些適合使用static的變量聲明為靜態變量。 變量聲明為static的使用場景&#xff1a; &#xff08;1&#xff09;變量所…

Linux內核的裁剪和移植

linux內核的裁剪和移植具體都在這個網址里面。https://blog.csdn.net/xie0812/article/details/10816059https://blog.csdn.net/xie0812/article/details/10821779轉載于:https://blog.51cto.com/13401435/2145947

李開復唱衰互聯網手機:大部分公司會失敗

摘要&#xff1a;互聯網企業和手機制造企業之間巨大的鴻溝也被李開復鮮明地指出來&#xff1a;“兩個產業差別巨大&#xff0c;企業基因不同。”百度此前也坦誠表示&#xff0c;與長虹合作的千元機&#xff0c;主要是針對2000元以下的用戶體驗&#xff0c;不能與四五千元的蘋果…