Merge remote-tracking branch 'origin/master'

# Conflicts:
#	pom.xml
This commit is contained in:
wyl
2022-05-14 21:35:28 +08:00
43 changed files with 1631 additions and 1 deletions
+19 -1
View File
@@ -14,6 +14,8 @@
<module>file-read</module>
<module>kafka</module>
<module>chain-of-responsibility</module>
<module>spring-boot</module>
<module>redis</module>
</modules>
<packaging>pom</packaging>
<properties>
@@ -27,13 +29,24 @@
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
@@ -47,6 +60,12 @@
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
@@ -57,6 +76,5 @@
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</project>
+25
View File
@@ -0,0 +1,25 @@
<?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">
<parent>
<artifactId>JavaBasiceDemo</artifactId>
<groupId>com.wyl.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>redis</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,31 @@
package com.wyl.demo.redission;
import com.wyl.demo.redission.conf.RedissonConf;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
public class RedisLock extends Thread {
static RedissonClient redissonClient = RedissonConf.getRedissonClient();
@Override
public void run() {
lock();
}
public void lock() {
RLock lock = redissonClient.getLock("wyl_lock");
lock.lock();
try {
System.out.println("获取到锁了");
Thread.sleep(5000000);
}
catch (InterruptedException e) {
System.err.println(e);
}
finally {
System.out.println("解锁了");
lock.unlock();
}
}
}
@@ -0,0 +1,16 @@
package com.wyl.demo.redission;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
@Data
public class RedisObject implements Serializable {
String name;
LocalDateTime createTime;
Long time;
List<String> tmp = Arrays.asList("123", "234", "345");
}
@@ -0,0 +1,32 @@
package com.wyl.demo.redission.conf;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
/**
*
* @ClassName: RedissonConf
* @Date: 2022/3/3 22:37
* @author wangyl
* @version V1.0
*/
public class RedissonConf {
private volatile static RedissonClient redissonClient;
public static RedissonClient getRedissonClient() {
if (redissonClient == null) {
synchronized (RedissonConf.class) {
if (redissonClient == null) {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://192.168.123.102:6379")
.setDatabase(0);
return Redisson.create(config);
}
}
}
return redissonClient;
}
}
@@ -0,0 +1,57 @@
package com.wyl.demo.redission;
import com.wyl.demo.redission.conf.RedissonConf;
import org.junit.jupiter.api.Test;
import org.redisson.api.RAtomicDouble;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
public class RedissonTest {
@Test
public void RedisStringTest() {
RedissonClient redissonClient = RedissonConf.getRedissonClient();
RAtomicDouble wyl = redissonClient.getAtomicDouble("wyl");
double v = wyl.get();
System.out.println(v);
}
@Test
public void RedisBloomFilterTest() {
RedissonClient redissonClient = RedissonConf.getRedissonClient();
RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("bloomFilter");
bloomFilter.tryInit(100, 0);
bloomFilter.add("123");
bloomFilter.add("124");
boolean contains = bloomFilter.contains("456");
long count = bloomFilter.count();
boolean contains1 = bloomFilter.contains("123");
System.out.println(count);
}
@Test
public void RedisObjectTest() {
RedissonClient redissonClient = RedissonConf.getRedissonClient();
RedisObject redisObject = new RedisObject();
redisObject.setName("1230");
redisObject.setCreateTime(LocalDateTime.now());
redisObject.setTime(123L);
RBucket<RedisObject> testObject = redissonClient.getBucket("testObject");
if (!testObject.isExists()) {
testObject.set(redisObject, 10, TimeUnit.SECONDS);
}
RedisObject redisObject1 = testObject.get();
System.out.println(redisObject1);
}
@Test
public void RedisLockTest() throws InterruptedException {
for (int i = 0; i < 100; i++){
new RedisLock().start();
}
Thread.sleep(1000000);
}
}
+34
View File
@@ -0,0 +1,34 @@
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>JavaBasiceDemo</artifactId>
<groupId>com.wyl.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>spring-boot-drools</module>
<module>spring-boot-xxjob</module>
</modules>
<artifactId>spring-boot</artifactId>
<packaging>pom</packaging>
<name>spring-boot</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
+74
View File
@@ -0,0 +1,74 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wyl</groupId>
<artifactId>spring-boot-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-common</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,22 @@
package com.wyl.spring.boot.common;
import com.wyl.spring.boot.common.bean.init.BeanInitExample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class SpringBootCommonApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootCommonApplication.class, args);
}
@Bean
BeanInitExample beanInitExample() {
return new BeanInitExample();
}
}
@@ -0,0 +1,18 @@
package com.wyl.spring.boot.common.aop.advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
/**
* DATE 4:45 PM
*
* @author mzt.
*/
public class LogAdvisor extends AbstractBeanFactoryPointcutAdvisor {
LogPointcut logPointcut = new LogPointcut();
@Override
public Pointcut getPointcut() {
return logPointcut;
}
}
@@ -0,0 +1,25 @@
package com.wyl.spring.boot.common.aop.advisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LogAutoConfigure {
@Bean
LogPointcut logPointcut() {
return new LogPointcut();
}
@Bean
LogAdvisor logAdvisor() {
LogAdvisor logAdvisor = new LogAdvisor();
logAdvisor.setAdvice(logInterceptor());
return logAdvisor;
}
@Bean
LogInterceptor logInterceptor() {
return new LogInterceptor();
}
}
@@ -0,0 +1,23 @@
package com.wyl.spring.boot.common.aop.advisor;
import com.wyl.spring.boot.common.spel.service.Evaluator;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* @author: wangyl
* @date: 2022/5/1
* @description: 再方法执行前以及执行进行代理操作
*/
public class LogInterceptor implements MethodInterceptor {
private final Evaluator evaluator = new Evaluator();
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Advisor 方法执行前");
Object proceed = invocation.proceed();
System.out.println("Advisor 方法执行后");
return proceed;
}
}
@@ -0,0 +1,21 @@
package com.wyl.spring.boot.common.aop.advisor;
import com.wyl.spring.boot.common.aop.annotation.LogTest;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* @author: wangyl
* @date: 2022/4/30
* @description: apo静态切入点,切入所有matches返回true的方法
*/
public class LogPointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, Class<?> targetClass) {
LogTest annotation = method.getAnnotation(LogTest.class);
return !Objects.isNull(annotation);
}
}
@@ -0,0 +1,10 @@
package com.wyl.spring.boot.common.aop.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited//注解会被继承
@Documented
public @interface LogTest {
}
@@ -0,0 +1,65 @@
package com.wyl.spring.boot.common.aop.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 接口出入参数信息依赖swagger
*
* @author wangyl
* @version V1.0
* @ClassName: WebLogAspect
* @Date: 2022/1/5 22:58
*/
@Aspect
@Slf4j
@Component
public class LogAspect {
/**
* 以自定义 @WebLog 注解为切点
*/
@Pointcut("@annotation(com.wyl.spring.boot.common.aop.annotation.LogTest)")
public void webLog() {
}
/**
* 在切点之前织入
*
* @param joinPoint
* @throws Throwable
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("Aspect Before 打印");
}
/**
* 在切点之后织入
*
* @throws Throwable
*/
@After("webLog()")
public void doAfter() {
System.out.println("Aspect After 打印");
}
/**
* 环绕
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("webLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Aspect 方法执行前打印 打印");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("Aspect 方法执行后打印 打印");
return proceed;
}
}
@@ -0,0 +1,33 @@
package com.wyl.spring.boot.common.bean.init;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class BeanInitExample implements InitializingBean, DisposableBean {
public BeanInitExample() {
System.out.println("构造函数被调用");
}
@PostConstruct
public void init() {
System.out.println("PostConstruct 被调用");
}
@PreDestroy
public void disposable() {
System.out.println("PreDestroy 被调用");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 被调用");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 被调用");
}
}
@@ -0,0 +1,13 @@
package com.wyl.spring.boot.common.service;
import com.wyl.spring.boot.common.spel.bean.Order;
import java.util.List;
public interface LogTestService {
void test();
void testSPEL(Order order);
void testSPELList(List<Order> orders);
}
@@ -0,0 +1,30 @@
package com.wyl.spring.boot.common.service.impl;
import com.wyl.spring.boot.common.aop.annotation.LogTest;
import com.wyl.spring.boot.common.service.LogTestService;
import com.wyl.spring.boot.common.spel.annotation.SpelTest;
import com.wyl.spring.boot.common.spel.bean.Order;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LogTestServiceImpl implements LogTestService {
@Override
@LogTest
public void test() {
System.out.println("testLog");
}
@SpelTest(spel = "{#order.id}")
public void testSPEL(Order order) {
System.out.println(123);
}
@Override
@SpelTest(spel = "{#orders.![#this.id]}")
public void testSPELList(List<Order> orders) {
System.out.println();
}
}
@@ -0,0 +1,61 @@
package com.wyl.spring.boot.common.spel;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wyl.spring.boot.common.spel.annotation.SpelTest;
import com.wyl.spring.boot.common.spel.service.EvaluationContext;
import com.wyl.spring.boot.common.spel.service.Evaluator;
import com.wyl.spring.boot.common.spel.service.RootObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Slf4j
@Component
public class SpelTestAspect {
/**
* 日志SpEL解析器
*/
private final Evaluator evaluator = new Evaluator();
/**
* 日志切入点
*/
@Pointcut(value = "@annotation(com.wyl.spring.boot.common.spel.annotation.SpelTest)")
public void SpelTestPointCut() {
}
@Around(value = "SpelTestPointCut()")
public Object errorLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
proceedingJoinPoint.getArgs();
Signature signature = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
Object[] args = proceedingJoinPoint.getArgs();
Class targetClass = AopProxyUtils.ultimateTargetClass(proceedingJoinPoint.getTarget());
SpelTest annotation = method.getAnnotation(SpelTest.class);
/**
* 生成元数据
*/
RootObject rootObject = new RootObject();
/**
* 生成spel上下文
*/
EvaluationContext context = new EvaluationContext(rootObject, method, args, evaluator.getDiscoverer());
/**
* 解析spel
*/
Object content = evaluator.parse(annotation.spel(), context);
System.out.println(content);
return proceedingJoinPoint.proceed();
}
}
@@ -0,0 +1,15 @@
package com.wyl.spring.boot.common.spel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SpelTest {
/**
* spel
*/
String spel();
}
@@ -0,0 +1,9 @@
package com.wyl.spring.boot.common.spel.bean;
import lombok.Data;
@Data
public class Order {
Integer id;
String name;
}
@@ -0,0 +1,22 @@
package com.wyl.spring.boot.common.spel.service;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.ParameterNameDiscoverer;
import java.lang.reflect.Method;
/**
* @author: wangyl
* @date: 2022/5/8
* @description: 解析上下文, 用于整个解析环境
*/
public class EvaluationContext extends MethodBasedEvaluationContext {
/**
* 构造方法
*
* @param rootObject 数据来源对象
* @param discoverer 参数解析器
*/
public EvaluationContext(RootObject rootObject, Method method, Object[] arguments, ParameterNameDiscoverer discoverer) {
super(rootObject, method, arguments, discoverer);
}
}
@@ -0,0 +1,52 @@
package com.wyl.spring.boot.common.spel.service;
import lombok.Getter;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* @author: wangyl
* @date: 2022/5/8
* @description: spel解析处理器
*/
@Getter
public class Evaluator {
/**
* SpEL解析器
*/
private final SpelExpressionParser parser = new SpelExpressionParser();
/**
* 参数解析器
*/
private final ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
/**
* 表达式模板
*/
private final ParserContext template = new TemplateParserContext("{", "}");
/**
* 解析
*
* @param expression 表达式
* @param context 日志表达式上下文
* @return 表达式结果
*/
public Object parse(String expression, EvaluationContext context) {
return getExpression(expression).getValue(context);
}
/**
* 获取翻译后表达式
*
* @param expression 字符串表达式
* @return 翻译后表达式
*/
private Expression getExpression(String expression) {
return getParser().parseExpression(expression, template);
}
}
@@ -0,0 +1,15 @@
package com.wyl.spring.boot.common.spel.service;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: wangyl
* @date: 2022/5/8
* @description: spel解析得元数据
*/
@Getter
@AllArgsConstructor
public class RootObject {
}
@@ -0,0 +1,51 @@
package com.wyl.spring.boot.common;
import com.wyl.spring.boot.common.service.LogTestService;
import com.wyl.spring.boot.common.spel.bean.Order;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class SpringBootCommonApplicationTests {
@Autowired
LogTestService logTestService;
@Test
void beanInit() {
}
@Test
void LogTestServiceTest() {
logTestService.test();
}
@Test
void SpelTest() {
Order order = new Order();
order.setId(123);
order.setName("wyl");
logTestService.testSPEL(order);
}
@Test
void SpelListTest() {
Order order1 = new Order();
order1.setId(1);
order1.setName("wyl1");
Order order2 = new Order();
order2.setId(2);
order2.setName("wyl2");
Order order3 = new Order();
order3.setId(3);
order3.setName("wyl3");
List<Order> orders = Arrays.asList(order1, order2, order3);
logTestService.testSPELList(orders);
}
}
+22
View File
@@ -0,0 +1,22 @@
<?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">
<parent>
<artifactId>spring-boot</artifactId>
<groupId>com.wyl.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-drools</artifactId>
<name>spring-boot-drools</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
</dependencyManagement>
</project>
@@ -0,0 +1,5 @@
package com.wyl.example.service;
public interface Service {
void test();
}
@@ -0,0 +1,8 @@
package com.wyl.example.service;
public class ServiceTest implements Service{
@Override
public void test() {
}
}
+68
View File
@@ -0,0 +1,68 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wyl.example</groupId>
<artifactId>spring-boot</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<groupId>com.wyl</groupId>
<artifactId>spring-boot-xxjob</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-xxjob</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>fastjson</artifactId>-->
<!-- <version>1.2.78</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,13 @@
package com.wyl.springbootxxjob;
import com.wyl.springbootxxjob.config.JobServerConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(JobServerConfig.class)
public @interface EnableXxljobRest {
}
@@ -0,0 +1,13 @@
package com.wyl.springbootxxjob;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootXxjobApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootXxjobApplication.class, args);
}
}
@@ -0,0 +1,54 @@
package com.wyl.springbootxxjob.config;
import com.wyl.springbootxxjob.service.DynamicXxlJobService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
@Configuration
@Getter
@Slf4j
public class JobServerConfig {
@Value("${xxl-job.http.serve.admin.addresses}")
private String adminAddresses;
@Value("${xxl-job.http.job.server.userName}")
private String userName;
@Value("${xxl-job.http.job.server.password}")
private String password;
@Bean("xxJobRestTemplate")
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
return restTemplate;
}
@Bean
DynamicXxlJobService dynamicXxlJobService() {
return new DynamicXxlJobService();
}
/**
* 使用OkHttpClient作为底层客户端
*
* @return
*/
private ClientHttpRequestFactory getClientHttpRequestFactory() {
OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.build();
return new OkHttp3ClientHttpRequestFactory(okHttpClient);
}
}
@@ -0,0 +1,50 @@
package com.wyl.springbootxxjob.job;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.sound.midi.Soundbank;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
* XxlJob开发示例(Bean模式)
* <p>
* 开发步骤:
* 1、任务开发:在Spring Bean实例中,开发Job方法;
* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;
* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;
*
* @author xuxueli 2019-12-11 21:52:51
*/
@Component
public class SampleXxlJob {
private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("wylDemoHandler")
public void demoJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
System.out.println(XxlJobHelper.getJobParam());
System.out.println(XxlJobHelper.getJobId());
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
// default success
}
}
@@ -0,0 +1,77 @@
package com.wyl.springbootxxjob.job;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
@@ -0,0 +1,107 @@
package com.wyl.springbootxxjob.obj;
import lombok.Data;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
* @author: wangyl
* @date: 2022/4/27
* @description: 创建任务对象
*/
@Data
public class JobEntity {
/**
* 任务id 修改是需要填写
*/
Integer id;
/**
* 执行器主键ID
*/
String jobGroup = "";
/**
* job描述
*/
String jobDesc = "";
/**
* 作者
*/
String author = "xxl-job-rest";
/**
* 调度类型
*/
String scheduleType = "CRON";
/**
* 调度配置,值含义取决于调度类型
*/
String scheduleConf = "";
/**
* 调度过期策略
*/
String cronGenDisplay = "";
/**
*
*/
String scheduleConfCRON = "";
/**
* GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
*/
String glueType = "BEAN";
/**
* 执行器,任务Handler名称
*/
String executorHandler = "";
/**
* 执行器,任务参数
*/
String executorParam = "";
/**
* 执行器路由策略
*/
String executorRouteStrategy = "FIRST";
/**
* 调度过期策略
*/
String misfireStrategy = "DO_NOTHING";
/**
* 阻塞处理策略
*/
String executorBlockStrategy = "SERIAL_EXECUTION";
/**
* 任务执行超时时间,单位秒
*/
String executorTimeout = "0";
/**
* 失败重试次数
*/
String executorFailRetryCount = "0";
/**
* GLUE备注
*/
String glueRemark = "";
public MultiValueMap<String, String> makeParam() {
MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
paramMap.add("jobGroup", jobGroup);
paramMap.add("jobDesc", jobDesc);
paramMap.add("author", author);
paramMap.add("scheduleType", scheduleType);
paramMap.add("scheduleConf", scheduleConf);
paramMap.add("cronGen_display", cronGenDisplay);
paramMap.add("glueType", glueType);
paramMap.add("executorHandler", executorHandler);
paramMap.add("executorParam", executorParam);
paramMap.add("executorRouteStrategy", executorRouteStrategy);
paramMap.add("misfireStrategy", misfireStrategy);
paramMap.add("executorBlockStrategy", executorBlockStrategy);
paramMap.add("executorTimeout", executorTimeout);
paramMap.add("executorFailRetryCount", executorFailRetryCount);
paramMap.add("glueRemark", glueRemark);
paramMap.add("schedule_conf_CRON", scheduleConfCRON);
if (id != null) {
paramMap.add("id", id.toString());
}
return paramMap;
}
}
@@ -0,0 +1,34 @@
package com.wyl.springbootxxjob.obj;
import lombok.Data;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
* @author: wangyl
* @date: 2022/4/27
* @description: 立即执行任务参数
*/
@Data
public class JobTriggerEntity {
/**
* 任务id
*/
Integer id;
/**
* 执行参数
*/
String executorParam;
/**
* 执行任务机器ip列表
*/
String addressList;
public MultiValueMap<String, String> makeParam() {
MultiValueMap<String, String> hashMap = new LinkedMultiValueMap<>();
hashMap.add("id", id.toString());
hashMap.add("executorParam", executorParam);
hashMap.add("addressList", addressList);
return hashMap;
}
}
@@ -0,0 +1,29 @@
package com.wyl.springbootxxjob.obj;
import lombok.Data;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
* @author: wangyl
* @date: 2022/4/27
* @description: xx-job 登录对象
*/
@Data
public class LoginEntity {
/**
* 用户名
*/
String userName = "";
/**
* 密码
*/
String password = "";
public MultiValueMap<String, String> makeParam() {
MultiValueMap<String, String> hashMap = new LinkedMultiValueMap<>();
hashMap.add("userName", userName);
hashMap.add("password", password);
return hashMap;
}
}
@@ -0,0 +1,31 @@
package com.wyl.springbootxxjob.obj;
import lombok.Data;
/**
* @author: wangyl
* @date: 2022/4/27
* @description: xx-job请求返回对象
*/
@Data
public class Result<T> {
/**
* 操作吗
*/
private Integer code;
/**
* 错误信息
*/
private String msg;
/**
* 结果信息
*/
private T content;
/**
* 操作成功
*/
public Boolean succeed() {
return 200 == code;
}
}
@@ -0,0 +1,232 @@
package com.wyl.springbootxxjob.service;
import com.wyl.springbootxxjob.config.JobServerConfig;
import com.wyl.springbootxxjob.obj.JobEntity;
import com.wyl.springbootxxjob.obj.JobTriggerEntity;
import com.wyl.springbootxxjob.obj.LoginEntity;
import com.wyl.springbootxxjob.obj.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Service
@Slf4j
public class DynamicXxlJobService {
/**
* 登录url
*/
static private String LOGIN_URL;
/**
* 创建任务的url
*/
static private String CREATE_JOB;
/**
* 创建任务的url
*/
static private String UPDATE_JOB;
/**
* 删除任务的url
*/
static private String REMOVE_JOB;
/**
* 启动任务的url
*/
static private String START_JOB;
/**
* 停止任务的url
*/
static private String STOP_JOB;
/**
* 立即执行任务url
*/
static private String TRIGGER_JOB;
@PostConstruct
public void init() {
LOGIN_URL = jobServerConfig.getAdminAddresses() + "/login";
CREATE_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/add";
UPDATE_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/update";
REMOVE_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/remove";
START_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/start";
STOP_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/stop";
TRIGGER_JOB = jobServerConfig.getAdminAddresses() + "/jobinfo/trigger";
}
@Resource
private JobServerConfig jobServerConfig;
@Resource(name = "xxJobRestTemplate")
RestTemplate restTemplate;
/**
* 创建定时任务
*
* @param jobEntity
* @return java.lang.Integer
* @Date 2022/4/27
* @Author wangyl
*/
public Integer createJob(JobEntity jobEntity) {
MultiValueMap<String, String> creatJonParam = jobEntity.makeParam();
ResponseEntity<Result> responseEntity = this.postFrom(CREATE_JOB, creatJonParam, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("创建任务失败,参数为;" + creatJonParam + "错误为:" + body.getMsg());
throw new RuntimeException();
}
Object jobId = body.getContent();
return Integer.valueOf(jobId.toString());
}
/**
* 更新定时任务信息
* @param jobEntity
* @return boolean
* @Date 2022/4/28
* @Author wangyl
*/
public boolean updateJob(JobEntity jobEntity) {
MultiValueMap<String, String> creatJonParam = jobEntity.makeParam();
ResponseEntity<Result> responseEntity = this.postFrom(UPDATE_JOB, creatJonParam, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("更新任务失败,参数为;" + creatJonParam + "错误为:" + body.getMsg());
throw new RuntimeException(body.getMsg());
}
return true;
}
public boolean triggerJob(JobTriggerEntity jobTriggerEntity) {
MultiValueMap<String, String> jobTriggerParam = jobTriggerEntity.makeParam();
ResponseEntity<Result> responseEntity = this.postFrom(TRIGGER_JOB, jobTriggerParam, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("立即执行任务失败,参数为;" + jobTriggerEntity + "错误为:" + body.getMsg());
throw new RuntimeException();
}
return true;
}
/**
* 启动固定任务
*
* @param jobId jobId
* @return 启动固定任务
*/
public boolean startJob(Integer jobId) {
MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
paramMap.add("id", String.valueOf(jobId));
ResponseEntity<Result> responseEntity = postFrom(START_JOB, paramMap, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("job:" + jobId + "启动失败,失败理由:" + body.getMsg());
throw new RuntimeException(body.getMsg());//todo 替换异常对象
}
return true;
}
/**
* 停止任务
*
* @param jobId
* @return boolean
* @Date 2022/4/27
* @Author wangyl
*/
public boolean stopJob(Integer jobId) {
MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
paramMap.add("id", String.valueOf(jobId));
ResponseEntity<Result> responseEntity = postFrom(STOP_JOB, paramMap, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("job:" + jobId + "停止失败,失败理由:" + body.getMsg());
throw new RuntimeException(body.getMsg());//todo 替换异常对象
}
return true;
}
/**
* 删除指定任务
*
* @param jobId 任务id
* @return boolean
* @Date 2022/4/27
* @Author wangyl
*/
public boolean removeJob(Integer jobId) {
MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
paramMap.add("id", String.valueOf(jobId));
ResponseEntity<Result> responseEntity = postFrom(REMOVE_JOB, paramMap, true);
Result body = responseEntity.getBody();
if (!body.succeed()) {
log.error("job:" + jobId + "删除失败,失败理由:" + body.getMsg());
throw new RuntimeException(body.getMsg());//todo 替换异常对象
}
return true;
}
/**
* 登录xx-job获取cookies
*
* @param
* @return java.util.List<java.lang.String>
* @Date 2022/4/27
* @Author wangyl
*/
public List<String> getCookie() {
LoginEntity loginEntity = new LoginEntity();
loginEntity.setUserName(jobServerConfig.getUserName());
loginEntity.setPassword(jobServerConfig.getPassword());
MultiValueMap<String, String> loginParam = loginEntity.makeParam();
ResponseEntity<Result> responseEntity = this.postFrom(LOGIN_URL, loginParam, false);
Result result = responseEntity.getBody();
if (!result.succeed()) {
log.error("登录xx-job失败", result.getMsg());
throw new RuntimeException(result.getMsg());//todo 替换异常对象
}
List<String> cookies = responseEntity.getHeaders().get("Set-Cookie");
return cookies;
}
/**
* 发送post的 form 请求
*
* @param url 请求url
* @param hashMap 请求参数
* @return java.lang.String
* @Date 2022/4/27
* @Author wangyl
*/
public ResponseEntity<Result> postFrom(String url, MultiValueMap<String, String> hashMap, Boolean needCookies) {
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
if (needCookies && CollectionUtils.isEmpty(cookies)) {
cookies = getCookie();
headers.put(HttpHeaders.COOKIE, cookies);
}
// 请求头设置,x-www-form-urlencoded格式的数据
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(hashMap, headers);
ResponseEntity<Result> responseEntity = restTemplate.postForEntity(url, request, Result.class);
if (!(responseEntity.getStatusCode() == HttpStatus.OK)) {
log.error("请求url" + url + ",param" + hashMap + " result" + responseEntity);
throw new RuntimeException("");//TODO 修改为异常
}
return responseEntity;
}
}
@@ -0,0 +1,16 @@
xxl-job.http.serve.admin.addresses=http://192.168.3.10:8080/xxl-job-admin/
xxl-job.http.job.server.userName = admin
xxl-job.http.job.server.password = 123456
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://192.168.3.10:8080/xxl-job-admin
xxl.job.accessToken=
xxl.job.executor.appname=wyl-first-test
xxl.job.executor.address=
xxl.job.executor.ip=
xxl.job.executor.port=9999
xxl.job.executor.logpath=./logs
xxl.job.executor.logretentiondays=30
@@ -0,0 +1,15 @@
package com.wyl.springbootxxjob;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseTest.Application.class)
public class BaseTest {
@ComponentScan(value = "com.wyl.springbootxxjob")
public static class Application {
}
}
@@ -0,0 +1,83 @@
package com.wyl.springbootxxjob;
import com.wyl.springbootxxjob.obj.JobEntity;
import com.wyl.springbootxxjob.obj.JobTriggerEntity;
import com.wyl.springbootxxjob.service.DynamicXxlJobService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.List;
class SpringBootXxjobApplicationTests extends BaseTest {
@Autowired
DynamicXxlJobService dynamicXxlJobService;
@Test
void getCookiesTest() {
List<String> cookie = dynamicXxlJobService.getCookie();
System.out.println(cookie);
}
@Test
void createJobTest() {
JobEntity jobEntity = new JobEntity();
jobEntity.setJobGroup("2");
jobEntity.setJobDesc("测试项目"+ LocalDateTime.now());
jobEntity.setAuthor("wyl");
jobEntity.setScheduleConf("* * * * * ?");
jobEntity.setCronGenDisplay("* * * * * ?");
jobEntity.setGlueType("BEAN");
jobEntity.setExecutorHandler("wylDemoHandler");
jobEntity.setExecutorRouteStrategy("FIRST");
jobEntity.setMisfireStrategy("DO_NOTHING");
jobEntity.setExecutorTimeout("0");
jobEntity.setExecutorFailRetryCount("0");
jobEntity.setGlueRemark("wyl测试新建项目");
Integer job = dynamicXxlJobService.createJob(jobEntity);
}
@Test
void updateJobTest() {
JobEntity jobEntity = new JobEntity();
jobEntity.setId(7);
jobEntity.setJobGroup("2");
jobEntity.setJobDesc("测试项目"+ LocalDateTime.now()+"更新");
jobEntity.setAuthor("wyl");
jobEntity.setScheduleConf("* * * * * ?");
jobEntity.setCronGenDisplay("* * * * * ?");
jobEntity.setGlueType("BEAN");
jobEntity.setExecutorHandler("wylDemoHandler");
jobEntity.setExecutorRouteStrategy("FIRST");
jobEntity.setMisfireStrategy("DO_NOTHING");
jobEntity.setExecutorTimeout("0");
jobEntity.setExecutorFailRetryCount("0");
jobEntity.setGlueRemark("wyl测试新建项目");
dynamicXxlJobService.updateJob(jobEntity);
}
@Test
void triggerJobTest() {
JobTriggerEntity jobTriggerEntity = new JobTriggerEntity();
jobTriggerEntity.setId(5);
jobTriggerEntity.setExecutorParam("123");
dynamicXxlJobService.triggerJob(jobTriggerEntity);
}
@Test
void startJobTest() {
boolean b = dynamicXxlJobService.startJob(3);
}
@Test
void stopJobJobTest() {
boolean b = dynamicXxlJobService.stopJob(3);
}
@Test
void removeJobTest() {
boolean b = dynamicXxlJobService.removeJob(1);
}
}