动态定时任务与动态生成class代码

动态定时任务

原理

采用定时任务线程池ThreadPoolTaskScheduler来实现定时任务。动态定时任务就是可以配置的,而不是写死在代码中。所以我们要将其写入到数据库中,然后暴露接口就可以进行配置比如创建、启动、结束任务。

数据库脚本


DROP TABLE IF EXISTS `tb_task`;
CREATE TABLE `tb_task`  (`task_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '定时任务id',`task_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务名称',`task_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务描述',`task_exp` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务Cron表达式',`task_status` int(0) NULL DEFAULT NULL COMMENT '定时任务状态,0停用 1启用',`task_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务的Runnable任务类完整路径',`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`task_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '动态定时任务表' ROW_FORMAT = Compact;INSERT INTO `tb_task` VALUES ('1', '测试打印helloworld', '这是一个描述', '0/10 * * * * ? ', 0, 'com.example.demo.Task.HelloTask', '2022-05-16 09:59:03', NULL);
INSERT INTO `tb_task` VALUES ('2', '这是一个含参数的task', '这是一个描述', '0/10 * * * * ? ', 0, 'com.example.demo.Task.parameterTask', '2022-05-16 10:41:10', NULL);

实体类

package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** <p>* 动态定时任务表* </p>** @author author* @since 2022-05-13*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_task")
public class TbTask implements Serializable {private static final long serialVersionUID = 1L;/*** 定时任务id*/@TableId(value = "task_id", type = IdType.NONE)private String taskId;/*** 定时任务名称*/@TableField("task_name")private String taskName;/*** 定时任务描述*/@TableField("task_desc")private String taskDesc;/*** 定时任务Cron表达式*/@TableField("task_exp")private String taskExp;/*** 定时任务状态,0停用 1启用*/@TableField("task_status")private Integer taskStatus;/*** 定时任务的Runnable任务类完整路径*/@TableField("task_class")private String taskClass;/*** 更新时间*/@TableField("update_time")private Date updateTime;/*** 创建时间*/@TableField("create_time")private Date createTime;}

定时任务实现类

package com.example.demo.component;import com.example.demo.entity.TbTask;
import com.example.demo.mapper.TbTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;@Slf4j
@Component
public class TaskScheduler {//数据库的任务public static ConcurrentHashMap<String, TbTask> tasks = new ConcurrentHashMap<>(10);//正在运行的任务public static ConcurrentHashMap<String, ScheduledFuture> runTasks = new ConcurrentHashMap<>(10);//线程池任务调度private final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();@Autowiredprivate TbTaskMapper tbTaskMapper;/*** 初始化线程池任务调度* 参数可由配置文件导入*/@Autowiredpublic TaskScheduler() {this.threadPoolTaskScheduler.setPoolSize(10);this.threadPoolTaskScheduler.setThreadNamePrefix("task-thread-");this.threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);this.threadPoolTaskScheduler.initialize();}/*** 获取所有数据库里的定时任务*/public void getAllTbTask() {//查询所有,并put到tasksTaskScheduler.tasks.clear();List<TbTask> list = tbTaskMapper.selectList(null);list.forEach((task) -> TaskScheduler.tasks.put(task.getTaskId(), task));}/*** 根据定时任务id,启动定时任务*/public void start(String taskId) {try {//如果为空,重新获取if (TaskScheduler.tasks.size() <= 0) {this.getAllTbTask();}TbTask tbTask = TaskScheduler.tasks.get(taskId);if (tbTask == null) {tbTask = tbTaskMapper.selectById(taskId);}if (tbTask == null)throw new RuntimeException("task不存在");//获取并实例化Runnable任务类Class<?> clazz = Class.forName(tbTask.getTaskClass());Runnable runnable = (Runnable) clazz.newInstance();//Cron表达式CronTrigger cron = new CronTrigger(tbTask.getTaskExp());//执行,并put到runTasksTaskScheduler.runTasks.put(taskId, Objects.requireNonNull(this.threadPoolTaskScheduler.schedule(runnable, cron)));this.updateTaskStatus(taskId, 1);log.info("{},任务启动!", taskId);} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {log.error("{},任务启动失败...", taskId);e.printStackTrace();}}public void start(String taskId,Runnable runnable) {try {//如果为空,重新获取if (TaskScheduler.tasks.size() <= 0) {this.getAllTbTask();}TbTask tbTask = TaskScheduler.tasks.get(taskId);if (tbTask == null) {tbTask = tbTaskMapper.selectById(taskId);}if (tbTask == null)throw new RuntimeException("task不存在");//Cron表达式CronTrigger cron = new CronTrigger(tbTask.getTaskExp());//执行,并put到runTasksTaskScheduler.runTasks.put(taskId, Objects.requireNonNull(this.threadPoolTaskScheduler.schedule(runnable, cron)));this.updateTaskStatus(taskId, 1);log.info("{},任务启动!", taskId);} catch (RuntimeException e) {log.error("{},任务启动失败...", taskId);e.printStackTrace();}}/*** 根据定时任务id,停止定时任务*/public void stop(String taskId) {// 停止任务TaskScheduler.runTasks.get(taskId).cancel(true);TaskScheduler.runTasks.remove(taskId);this.updateTaskStatus(taskId, 0);log.info("{},任务停止...", taskId);}/*** 更新数据库动态定时任务状态*/public void updateTaskStatus(String taskId, int status) {TbTask task = tbTaskMapper.selectById(taskId);task.setTaskStatus(status);task.setUpdateTime(new Date());tbTaskMapper.updateById(task);}}

controller以及postman调用

由于只是demo,有些未完善。

package com.example.demo.controller;import com.example.demo.Task.parameterTask;
import com.example.demo.component.TaskScheduler;
import com.example.demo.component.classGenerate;
import com.example.demo.entity.TbTask;
import com.example.demo.entity.VO.ResultVo;
import com.example.demo.service.ITbTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;@RestController
@RequestMapping("/demo/task")
public class TaskController {@AutowiredTaskScheduler taskScheduler;@AutowiredITbTaskService tbTaskService;/*** 添加并启动任务* @param tbTask* @return*/@PostMappingpublic ResultVo addTask(@RequestBody TbTask tbTask){tbTaskService.save(tbTask);String taskId = tbTask.getTaskId();taskScheduler.start(taskId);return ResultVo.SUCCESS("添加并启动成功").data("taskId",taskId);}/*** 添加并启动任务,含参任务* @param tbTask* @param name* @return*/@PostMapping("/{name}")public ResultVo addTask2(@RequestBody TbTask tbTask,@PathVariable("name") String name){tbTaskService.save(tbTask);String taskId = tbTask.getTaskId();parameterTask parameterTask = new parameterTask();parameterTask.setName(name);taskScheduler.start(taskId,parameterTask);return ResultVo.SUCCESS("添加并启动成功").data("taskId",taskId);}/*** 启动任务* @param taskId* @return*/@GetMapping("/start/{taskId}")public ResultVo start(@PathVariable("taskId") String taskId){taskScheduler.start(taskId);return ResultVo.SUCCESS("启动成功").data("taskId",taskId);}/*** 停止任务* @param taskId* @return*/@GetMapping("/stop/{taskId}")public ResultVo stop(@PathVariable("taskId") String taskId){taskScheduler.stop(taskId);return ResultVo.SUCCESS("停止任务").data("taskId",taskId);}@PostMapping("/generate")public ResultVo generateJava(@RequestBody HashMap<String,String> map) throws Exception {String path = map.get("path");String javaCode = map.get("javaCode");classGenerate.createStudentByFile(path,javaCode);return ResultVo.SUCCESS().message("代码生成成功");}
}

下面是postman测试
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

动态生成class

实现代码

package com.example.demo.component;import org.springframework.stereotype.Component;import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;/*** Class生成*/
public class classGenerate {/*** 生成java文件并加载class* @param path /com/example/demo/xxx/xxx.java 类生成路径* @param JavaCode 类代码* @throws Exception*/public static void createStudentByFile(String path,String JavaCode) throws Exception{
//        String fileName = System.getProperty("user.dir") + "/src/main/java"+path;
//        String fileName = "E:/data/JavaCode"+path;
//        String fileName = "/data/JavaCode"+path;// path = /com/xx/xxx/task/xxx.javaString fileName = path;logger.info("fileName:[{}]",fileName);File file = new File(fileName);if(!file.exists()){file.getParentFile().mkdirs();}FileWriter fileWriter = new FileWriter(file);fileWriter.write(JavaCode);fileWriter.flush();fileWriter.close();// xxx/classes/URL location = DemoApplication.class.getProtectionDomain().getCodeSource().getLocation();JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager manager = compiler.getStandardFileManager(null,null,null);Iterable<? extends JavaFileObject> javaFileObjects = manager.getJavaFileObjects(fileName);String dest = location.getPath();logger.info("dest: [ {} ]",dest);//options就是指定编译输入目录,与我们命令行写javac -d C://是一样的List<String> options = new ArrayList<String>();options.add("-d");options.add(dest);JavaCompiler.CompilationTask task = compiler.getTask(null,manager,null,options,null,javaFileObjects);task.call();manager.close();
//        URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir") + "/target/classes")};//加载class时要告诉你的classloader去哪个位置加载class文件//        ClassLoader classLoader = new URLClassLoader(urls);
//        Object student = classLoader.loadClass("com.example.demo.Task.HelloTask2").newInstance();}}

测试

 @PostMapping("/generate")public ResultVo generateJava(@RequestBody HashMap<String,String> map) throws Exception {String path = map.get("path");String javaCode = map.get("javaCode");classGenerate.createStudentByFile(path,javaCode);return ResultVo.SUCCESS().message("代码生成成功");}

postman
由于是传入代码,所以遇到换行要使用\n""转义使用\",否则会报错,在postman测试中json参数需要在一行中。
在这里插入图片描述

注意:原先我上述代码中使用了@Slf4j,但是这样的话class编译的时候会报错,没办法找到。可能是lombok的插件的原因吧。此外编译后,会有一些警告,但是不影响编译完成。

警告报错如下:
在这里插入图片描述

E:\project\hello_world\src\main\java\com\example\demo\Task\HelloTask2.java:4: 警告: Can't initialize javac processor due to (most likely) a class loader problem: java.lang.NoClassDefFoundError: com/sun/tools/javac/processing/JavacProcessingEnvironment
public class HelloTask2 implements Runnable{^at lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:85)at lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:87)at lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:140)at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:69)at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:500)at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:597)at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:690)at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)at com.sun.tools.javac.main.Main.compile(Main.java:523)at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)at com.example.demo.component.classGenerate.createStudentByFile(classGenerate.java:47)at com.example.demo.controller.TaskController.generateJava(TaskController.java:79)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:748)Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.processing.JavacProcessingEnvironmentat java.lang.ClassLoader.findClass(ClassLoader.java:523)at java.lang.ClassLoader.loadClass(ClassLoader.java:418)at lombok.launch.ShadowClassLoader.loadClass(ShadowClassLoader.java:422)at java.lang.ClassLoader.loadClass(ClassLoader.java:351)... 71 more
1 个警告

但是这个警告不影响!!
解决办法:
在SDKs中添加tools.jar ,路径一般在jdk/lib/ 下面
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

与动态定时任务结合

由于我们前面创建的是一个Runnable对象,所以我们可以对他进行创建定时任务
在这里插入图片描述

github地址

仓库链接

部署问题

由于是jar包部署,在生成Java文件和class文件时,无法加入到jar包中。对于这个问题,我采用解压jar包的方式运行。

image.png

具体步骤

# 解压到当前目录 会在当前目录生成 BOOT-INF、org、META-INF
jar -xf app.jar
#  指定入口  : 为分隔符 
# java -cp BOOT-INF/classes:BOOT-INF/lib/*  com.example.demo.DemoApplication
# 部署
nohup java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.demo.DemoApplication > nohup.log &

java org.springframework.boot.loader.JarLauncher 也能启动项目,但是无法生成class文件!

这样的话,class文件就可以写入到 解压后的jar的BOOT-INF/classes/路径下。

测试

创建生成代码

image.png

在jar包所在目录会生成上述传入的path结构的java代码。

image.png

image.png

并且在 BOOT-INF/classes也会生成对应的class文件。

image.png

启动任务

image.png

image.png

class文件生成的目录依赖于传入的Java代码中的 package com.example.demo.Task;,这样生成的class就会在 BOOT-INF/classes/com/example/demo/Task 目录下啦!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker登录mysql数据库_Docker下搭建mysql数据库

1.获取官方镜像&#xff1a;[rootCentos7 mysql]# docker pull mysql/mysql-server:latestlatest: Pulling from mysql/mysql-server1f5b026b07bc: Pull complete3d5697fc1304: Pull complete2747c84403db: Pull completedc0c445a852b: Pull completeDigest: sha256:7aba8c77f9…

LNMP与CA认证的童话故事

在前面的一篇博客中&#xff0c;我已经介绍过&#xff0c;如何通过源码编译安装LAMP&#xff0c;见教你源码编译制作LAMP详细过程 &#xff0c;这里就介绍下如何编译安装LNMP&#xff0c;以及如何在LNMP中添加ssl认证。LNMP&#xff0c;也叫做LEMP。L&#xff0c;即linux操作系…

Zabbix 最新版 5.2 版本源码安装

Zabbix 最新版 5.0 LTS 版本安装 zabbix 5.0 版本于 5 月 11 日正式发布&#xff0c;是最新的 LTS&#xff08;长期支持&#xff09;版本&#xff0c;5.0 带来很多功能和特性&#xff0c;后面会陆续推出文章介绍&#xff0c;下面主要介绍下 5.0 版本的安装。 环境要求 5.0 版…

【声卡驱动】安装realtek high definition audio后重启电脑被自动卸载替换成系统自带的realtek auto

解决步骤 先断网安装前先记录realtek auto的GUID&#xff0c;可以从设备管理器中事件中找到它&#xff0c;复制保留备用 安装 realtek high definition audio &#xff0c;重启&#xff08;断网&#xff09;在断网状态下&#xff0c;winr &#xff0c;输入gpedit.msc&#xff…

mysql explain是什么意思_mysql explain的作用是什么?

mysql explain的作用是模拟Mysql优化器是如何执行SQL查询语句的&#xff0c;从而知道Mysql是如何处理用户的SQL语句&#xff0c;提高数据检索效率&#xff0c;降低数据库的IO成本。mysql explain的作用是&#xff1a;模拟Mysql优化器是如何执行SQL查询语句的&#xff0c;从而知…

d3.js 搭建 d3-force-directed-graph 例子

d3.js 搭建 d3-force-directed-graph 例子 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <script src&q…

js 创建快捷方式

代码 <script type"text/javascript"language"javascript">//创建快捷方式[浏览器设置要低,ff不支持]functioncreateShortcut() { varfso newActiveXObject("Scripting.FileSystemObject"); varshell newActiveXObject(&quo…

OpenLDAP在linux上的部署和原理应用centos7

轻型目录访问协议&#xff08;英文&#xff1a;Lightweight Directory Access Protocol&#xff0c;缩写&#xff1a;LDAP&#xff09;是一个开放的&#xff0c;中立的&#xff0c;工业标准的应用协议&#xff0c;通过IP协议提供访问控制和维护分布式信息的目录信息。 OpenLDAP…

c# 检测cpu使用率[测试通过]

创建一个控制台应用程序&#xff0c;代码如下 代码 usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;//引用2命名空间usingSystem.Diagnostics;usingSystem.Threading;namespaceConsoleApplication1{ classProgram { staticvoidM…

mysql怎么修改表中的文字_mysql表中怎么修改字段?

在mysql表中&#xff0c;可以使用“ALTER TABLE 表名 CHANGE 旧字段名 新字段名 数据类型;”语句来修改字段名称&#xff1b;使用“ALTER TABLE 表名 MODIFY 字段名 新数据类型;”语句来修改字段数据类型。修改字段名称MySQL 中修改表字段名的语法规则如下&#xff1a;ALTER TA…

重置mariadb密码

基本的思路是&#xff0c;以安全模式启动MariaDB&#xff0c;这样不需要密码可以直接以root身份登录&#xff0c;然后重设密码。 在Centos 7.0上的操作步骤如下&#xff1a; 首先&#xff0c;我们停掉MariaDB服务&#xff1a; systemctl stop mariadb.service #停止MariaDB在…

asp.net 取windows的所有进程

代码如下&#xff1a; 代码 #region取得windows的所有进程publicstaticstringGetCourse(){ System.Text.StringBuilder sb newSystem.Text.StringBuilder(); stringtempName ""; intbegpos, endpos; foreach(Process thisProc inSystem.Diagnostics.Proc…

asp.net 操作ftp 通用代码[测试通过]

代码如下&#xff1a; 代码 //建立目录FtpWebRequest Request (FtpWebRequest)WebRequest.Create("ftp://113.107.160.135:2121/vadmin.uuu9.com/aaa"); Request.Credentials newNetworkCredential("wanglei", "}}XnJXt4a\7datr"); …

AirFlow官方入门DAG示例

经过前两篇文章的简单介绍之后&#xff0c;我们安装了自己的AirFlow以及简单了解了DAG的定义文件&#xff0e;现在我们要实现自己的一个DAG&#xff0e; 1. 启动Web服务器 使用如下命令启用: airflow webserver 现在可以通过将浏览器导航到启动Airflow的主机上的8080端口来…

三层业务类(DAL)必用的通用方法之一

写代码有两年多的时间了&#xff0c;越来越觉得代码的通用性是衡量一个程序员的标准。 代码 #regionSqlDataReader > List///<summary>///author:Stone_W///date:2010.11.29///desc:SqlDataReader 转 List///</summary>///<param name"dr">SqlD…

使用 Packer、Ansible 和 Terraform 构建不可变的基础设施Devops工具链

在容器编排领域&#xff0c;Kubernetes 已成为事实上的标准&#xff0c;而容器镜像 (Docker Image) 作为容器技术栈中最关键的创新之一&#xff0c;极大的推动了企业内部 Devops 运动的进程。 容器镜像所具有的轻量性、便携性、分层机制和内核共享机制真正意义上实现了 “Buil…

用于检测敏感词的 PHP 扩展

2019独角兽企业重金招聘Python工程师标准>>> 敏感词过滤是我朝程序员必须具备的一种特殊技能&#xff0c;随着敏感词越来越多&#xff0c;是时候写个扩展来快速的进行敏感词检测了使用说明 1. 安装 libdatrie tar zxf libdatrie-0.2.4.tar.gz cd libdatrie-0.2.4 .…

缓存通用管理类 + 缓存 HttpContext.Current.Cache 和 HttpRuntime.Cache 的区别

以前写asp.net时用HttpContext.Current.Cache存缓存很好用&#xff0c;今天写了一个windows服务程序&#xff0c;HttpContext.Current.Cache存缓存的时候还好&#xff0c;取的时候一直报错“未将对象引用到实例”很郁闷&#xff0c;查询了一下资料才明白引用程序缓存要用HttpRu…

Ubuntu 加速安装Opencv 3.4.3

Ubuntu 18.04 完美安装Opencv 3.4.3 1.1 下载Opencv 3.4.3 在http://opencv.org/网址中找到下载连接&#xff0c;版本选择&#xff1a;https://github.com/opencv/opencv/releases 下载地址&#xff1a;https://github.com/Itseez/opencv/archive/3.4.3.zip (此处可以使用w…

Net和T-sql中的日期函数操作

net中的日期函数代码&#xff1a; 代码 1 DateTime now DateTime.Now; 2 // 当前月的第一天 3 DateTime d1 new DateTime(now.Year, now.Month, 1); 4 // 当前月的最后一天 5 DateTime d2 d1.AddMonths(1).AddDays(-1); 6 if (now.Day d2.Day) 7 { 8 // 当日是当月最后…