您好,欢迎来到抵帆知识网。
搜索
您的当前位置:首页springboot注解Aspect实现方案

springboot注解Aspect实现方案

来源:抵帆知识网
springboot注解Aspect实现⽅案

⽬录

⽬标实现

POM⼀些实体类CheckedParamProcessDbModel测试⽤的⼊参对象⼀些⼯具类

BaseUtilSpringBootBeanUtilProcessBeanUtilCheckedTransmitableUtilPrivateTransmitableUtil⼀些Bean

PostProcessTestCheckPostProcessAspect注解切⾯类 CheckedAop线程池配置持久化service审批⽤的service测试⽤的service审批⽤的controller测试⽤的controller开启异步功能测试⽬标

本⽂提供⼀种⾃定义注解,来实现业务审批操作的DEMO,不包含审批流程的配置功能。具体⽅案是

⾃定义⼀个Aspect注解,拦截sevice⽅法,将拦截的信息持久化,待审批;审批时获取持久化数据,执⾏⽬标⽅法。

实现

POM

4.0.0

org.springframework.boot spring-boot-starter-parent 2.5.8

com.proc

process-test 1.0.0-SNAPSHOT process-test

Demo project for Spring Boot

1.8

org.springframework.boot spring-boot-starter-web

org.springframework.boot spring-boot-starter-test test

org.springframework.boot spring-boot-starter-aop

org.springframework.boot

spring-boot-configuration-processor true

com.alibaba

transmittable-thread-local 2.12.2

org.springframework.boot spring-boot-maven-plugin

⼀些实体类

CheckedParam

⽤于包装页⾯传进来的参数

package com.proc.model;import java.util.List;

public class CheckedParam {

//业务标记,由页⾯传⼊,⽤于审批时页⾯根据tagPageJs解析data,渲染到页⾯,审批管理员可看到审批的内容 private String tagPageJs; //页⾯传⼊的原始数据 private List data;

public String getTagPageJs() { return tagPageJs; }

public void setTagPageJs(String tagPageJs) { this.tagPageJs = tagPageJs; }

public List getData() { return data; }

public void setData(List data) { this.data = data; } }

ProcessDbModel

拦截的信息包装类,⽤于持久化数据

package com.proc.model;

public class ProcessDbModel { //bean的⽬标类全限定名

private String targetClassName;

//拦截到的service⽅法名 private String methodName;

//页⾯传⼊的tagPageJs或Checked注解的tag private String tag;

private String description;

//拦截到的service⼊参类型,包含泛型信息 private String paramTypes;

//拦截到的service⼊参值 private String paramArgs;

//拦截到的service⼊参值或页⾯传⼊的原始数据 private String data;

public String getTargetClassName() { return targetClassName; }

public void setTargetClassName(String targetClassName) { this.targetClassName = targetClassName; }

public String getMethodName() { return methodName; }

public void setMethodName(String methodName) { this.methodName = methodName; }

public String getTag() { return tag; }

public String getDescription() { return description; }

public void setDescription(String description) { this.description = description; }

public void setTag(String tag) { this.tag = tag; }

public String getParamTypes() { return paramTypes; }

public void setParamTypes(String paramTypes) { this.paramTypes = paramTypes; }

public String getParamArgs() { return paramArgs; }

public void setParamArgs(String paramArgs) { this.paramArgs = paramArgs; }

public String getData() { return data; }

public void setData(String data) { this.data = data; }

@Override

public String toString() {

return \"ProcessDbModel [targetClassName=\" + targetClassName + \ + \ + data + \"]\"; } }

测试⽤的⼊参对象

package com.proc.model;import java.math.BigDecimal;public class Score {

private BigDecimal langue;

private BigDecimal math;

private BigDecimal english;

public BigDecimal getLangue() { return langue; }

public void setLangue(BigDecimal langue) { this.langue = langue; }

public BigDecimal getMath() {

return math; }

public void setMath(BigDecimal math) { this.math = math; }

public BigDecimal getEnglish() { return english; }

public void setEnglish(BigDecimal english) { this.english = english; }

@Override

public String toString() {

return \"Score [langue=\" + langue + \ }}

package com.proc.model;import java.util.List;

public class Person { private String name;

private String age;

private String sex;

private String testName;

private String salary;

private String work;

private List grades; public String getName() { return name; }

public void setName(String name) { this.name = name; }

public String getAge() { return age; }

public void setAge(String age) { this.age = age; }

public String getSex() { return sex; }

public void setSex(String sex) { this.sex = sex; }

public String getSalary() { return salary; }

public void setSalary(String salary) { this.salary = salary; }

public String getTestName() { return testName; }

public void setTestName(String testName) { this.testName = testName; }

public String getWork() { return work; }

public void setWork(String work) { this.work = work; }

public List getGrades() { return grades; }

public void setGrades(List grades) { this.grades = grades; }

@Override

public String toString() {

return \"Person [name=\" + name + \ + salary + \ } }

⼀些⼯具类

JacksonCanonicalUtil

package com.proc.util;

import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.JavaType;

import com.fasterxml.jackson.databind.json.JsonMapper;public class JacksonCanonicalUtil {

private static final JsonMapper MAPPER = new JsonMapper(); private JacksonCanonicalUtil () {}

public static String toCanonical (Class clazz) {

return MAPPER.getTypeFactory().constructType(clazz).toCanonical(); }

public static String toCanonical (TypeReference tr) {

return MAPPER.getTypeFactory().constructType(tr).toCanonical(); }

//反序列化时从持久数据中获取JavaType

public static JavaType constructFromCanonical (String canonical) { return MAPPER.getTypeFactory().constructFromCanonical(canonical); }}

StringZipUtil

⽤于压缩和解压字符串,减少持久数据占⽤空间

package com.proc.util;

import java.io.ByteArrayOutputStream;import java.io.OutputStream;

import java.nio.charset.StandardCharsets;import java.util.Base;

import java.util.zip.DeflaterOutputStream;import java.util.zip.InflaterOutputStream;public class StringZipUtil { private StringZipUtil () {}

public static String zipBase(String text) {

try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { try (OutputStream os = new DeflaterOutputStream(out)) { os.write(text.getBytes(StandardCharsets.UTF_8)); }

return Base.getEncoder().encodeToString(out.toByteArray()); } catch (Exception e) {

throw new RuntimeException(\"压缩字符串出错\ } }

public static String unzipBase(String text) {

try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { try (OutputStream os = new InflaterOutputStream(out)) { os.write(Base.getDecoder().decode(text)); }

return new String(out.toByteArray(), StandardCharsets.UTF_8); } catch (Exception e) {

throw new RuntimeException(\"解压字符串出错\ } }}

BaseUtil

⼀些参数值转为Base后持久化

package com.proc.util;

import java.nio.charset.StandardCharsets;import java.util.ArrayList;import java.util.Base;import java.util.List;

import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.json.JsonMapper;public class BaseUtil { private BaseUtil () {}

private static final JsonMapper MAPPER = new JsonMapper();

public static String[] toStrings (Object[] objs) { List list = new ArrayList<>(); try {

for (Object obj : objs) {

list.add(MAPPER.writeValueAsString(obj)); }

} catch (Exception e) {

throw new RuntimeException(\"序列化对象出错\ }

return list.toArray(new String[0]); }

public static String encode (String[] strs) { List list = new ArrayList<>(); for (String str : strs) {

list.add(Base.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8))); }

String join = list.stream().collect(Collectors.joining(\"|\")); return join; }

public static String[] decode (String text) { String[] strs = text.split(\"\\\\|\

List list = new ArrayList<>(); for (String base : strs) {

list.add(new String(Base.getDecoder().decode(base), StandardCharsets.UTF_8)); }

return list.toArray(new String[0]); }

public static String encodeZip (Object[] objs) { return encodeZip(toStrings(objs)); }

public static String encodeZip (String[] strs) { List list = new ArrayList<>(); for (String str : strs) {

list.add(StringZipUtil.zipBase(str)); }

String join = list.stream().collect(Collectors.joining(\"|\")); return StringZipUtil.zipBase(join); }

public static String[] decodeZip (String text) { String str = StringZipUtil.unzipBase(text); String[] strs = str.split(\"\\\\|\

List list = new ArrayList<>(); for (String base : strs) {

list.add(StringZipUtil.unzipBase(base)); }

return list.toArray(new String[0]); }}

SpringBootBeanUtil

package com.proc.util;import java.util.Map;

import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;

@Component

public class SpringBootBeanUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext; @Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringBootBeanUtil.applicationContext = applicationContext; }

public static ApplicationContext getApplicationContext() { return applicationContext; }

public static Object getBean(String name) { return applicationContext.getBean(name); }

public static T getBean(Class clazz) { return (T) applicationContext.getBean(clazz); }

public static T getBean(String name, Class clazz) { return applicationContext.getBean(name, clazz); }

public static Map getBeansOfType(Class clazz) { return applicationContext.getBeansOfType(clazz); } }

ProcessBeanUtil⽤于执⾏⽬标⽅法

package com.proc.util;

import java.lang.reflect.Method;

import org.springframework.util.ReflectionUtils;public class ProcessBeanUtil { private ProcessBeanUtil () {}

public static Object excuteBeanMethod (String targetClassName, String methodName, Class[] parameterTypes, Object[] args) { Class targetClass; try {

targetClass = Class.forName(targetClassName); } catch (ClassNotFoundException e) {

throw new RuntimeException(\"未找到类\ }

return excuteBeanMethod(targetClass, methodName, parameterTypes, args); }

public static Object excuteBeanMethod (Class targetClass, String methodName, Class[] parameterTypes, Object[] args) { Object bean = SpringBootBeanUtil.getBean(targetClass);

Method method = ReflectionUtils.findMethod(targetClass, methodName, parameterTypes); return ReflectionUtils.invokeMethod(method, bean, args); }}

CheckedTransmitableUtil⽤于传递业务参数

package com.proc.util;

import com.alibaba.ttl.TransmittableThreadLocal;import com.proc.model.CheckedParam;public class CheckedTransmitableUtil {

private static final TransmittableThreadLocal threadLocal = new TransmittableThreadLocal<>();

private CheckedTransmitableUtil () {}

public static void set (CheckedParam checkedParam) { threadLocal.set(checkedParam); }

public static CheckedParam getAndRemove () { CheckedParam checkedParam = threadLocal.get();

threadLocal.remove(); return checkedParam; }}

PrivateTransmitableUtil为Aspect判断是否拦截提供依据

package com.proc.util;

import com.alibaba.ttl.TransmittableThreadLocal;public class PrivateTransmitableUtil {

private static final String CHECKED = \"__CHECKED__\";

private static final TransmittableThreadLocal threadLocal = new TransmittableThreadLocal<>();

private PrivateTransmitableUtil () {}

public static void set () {

threadLocal.set(CHECKED); }

//是否执⾏的审批程序

public static boolean isCheck () { String checked = threadLocal.get(); threadLocal.remove();

return CHECKED.equals(checked); }}

⼀些Bean

PostProcess

⽤于拦截⽅法后做的个性处理

package com.proc.bean;

public interface PostProcess { //返回说明内容,审批时在页⾯显⽰

String description(String tag, Class[] parameterTypes, Object[] args);

//返回代替的返回值

T retObject(String tag, Class[] parameterTypes, Object[] args);}

TestCheckPostProcess测试⽤

package com.proc.bean;

import org.springframework.stereotype.Component;@Component

public class TestCheckPostProcess implements PostProcess { @Override

public String description(String tag, Class[] parameterTypes, Object[] args) { return tag + \"测试testCheck\"; }

@Override

public String retObject(String tag, Class[] parameterTypes, Object[] args) { return tag + \"返回拦截响应\"; }}

Aspect注解

package com.proc.config;

import static java.lang.annotation.ElementType.METHOD;import static java.lang.annotation.RetentionPolicy.RUNTIME;import java.lang.annotation.Retention;import java.lang.annotation.Target;import com.proc.bean.PostProcess;@Retention(RUNTIME)@Target(METHOD)

public @interface Checked {

String tag() default \"\"; /**

* @see com.proc.util.JacksonCanonicalUtil * @return */

String[] paramCanonical();

Class> postProcess();}

切⾯类 CheckedAop

package com.proc.config;

import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.proc.bean.PostProcess;import com.proc.model.CheckedParam;import com.proc.model.ProcessDbModel;import com.proc.service.ProcessDbService;import com.proc.util.BaseUtil;

import com.proc.util.CheckedTransmitableUtil;import com.proc.util.PrivateTransmitableUtil;import com.proc.util.SpringBootBeanUtil;@Component@Aspect

public class CheckedAop {

@Autowired

private ProcessDbService processDbService; //拦截Checked注释的⽅法

@Pointcut(\"@annotation(com.proc.config.Checked)\") public void check() { }

@Around(value = \"com.proc.config.CheckedAop.check() && @annotation(checked)\")

public Object around(ProceedingJoinPoint joinPoint, Checked checked) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Class[] parameterTypes = signature.getParameterTypes(); String methodName = signature.getMethod().getName(); Object[] args = joinPoint.getArgs(); if (PrivateTransmitableUtil.isCheck()) { //审批后,执⾏业务代码

Object returnVal = joinPoint.proceed(); return returnVal; } else {

//不是审批操作,拦截

Class> postProcess = checked.postProcess(); PostProcess bean = SpringBootBeanUtil.getBean(postProcess); //组装持久化数据

ProcessDbModel dbModel = new ProcessDbModel();

dbModel.setTargetClassName(joinPoint.getTarget().getClass().getName()); dbModel.setMethodName(methodName); String tag = checked.tag();

CheckedParam checkedParam = CheckedTransmitableUtil.getAndRemove();

if (checkedParam == null || checkedParam.getTagPageJs() == null || checkedParam.getTagPageJs().isEmpty()) { //不是页⾯调⽤的业务,使⽤注解的tag,data保存为service的参数,这时需要页⾯专门解析渲染 String[] argStrs = BaseUtil.toStrings(args);

dbModel.setParamArgs(BaseUtil.encodeZip(argStrs)); dbModel.setData(BaseUtil.encode(argStrs)); } else {

tag = checkedParam.getTagPageJs();

dbModel.setParamArgs(BaseUtil.encodeZip(args));

dbModel.setData(BaseUtil.encode(checkedParam.getData().toArray(new String[0]))); }

dbModel.setTag(tag);

dbModel.setParamTypes(BaseUtil.encodeZip(checked.paramCanonical())); dbModel.setDescription(bean.description(tag, parameterTypes, args)); //持久化数据

processDbService.save(dbModel);

return bean.retObject(tag, parameterTypes, args); } }}

线程池配置

测试⽤

package com.proc.config;

import java.util.concurrent.Executor;

import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import com.alibaba.ttl.threadpool.TtlExecutors;@Configuration

public class TaskExecutePoolConfig { @Bean

public Executor processExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核⼼线程池⼤⼩

executor.setCorePoolSize(10); //最⼤线程数

executor.setMaxPoolSize(10); //队列容量

executor.setQueueCapacity(500); //活跃时间

executor.setKeepAliveSeconds(60); //线程名字前缀

executor.setThreadNamePrefix(\"ProcessExecutor-\");

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); // 等待所有任务结束后再关闭线程池

executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize();

//⽤transmittable-thread-local包装,才可以正确给线程池中的线程传递数据 return TtlExecutors.getTtlExecutor(executor); }}

持久化service

为测试⽅便,未真正实现持久化

package com.proc.service;

import com.proc.model.ProcessDbModel;public interface ProcessDbService { void save (ProcessDbModel model);

ProcessDbModel get ();}

package com.proc.service.impl;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;import com.proc.model.ProcessDbModel;import com.proc.service.ProcessDbService;

@Component

public class ProcessDbServiceImpl implements ProcessDbService {

private static final Logger log = LoggerFactory.getLogger(ProcessDbService.class);

private volatile ProcessDbModel model; @Override

public void save(ProcessDbModel model) { this.model = model;

log.info(model.toString());

}

@Override

public ProcessDbModel get() { return this.model; }}

审批⽤的service

package com.proc.service;

import com.proc.model.ProcessDbModel;public interface ProcessCheckService { void process (ProcessDbModel model);}

package com.proc.service.impl;import java.util.ArrayList;import java.util.List;import java.util.Objects;import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.JavaType;

import com.fasterxml.jackson.databind.json.JsonMapper;import com.proc.model.ProcessDbModel;

import com.proc.service.ProcessCheckService;import com.proc.util.BaseUtil;

import com.proc.util.JacksonCanonicalUtil;import com.proc.util.PrivateTransmitableUtil;import com.proc.util.ProcessBeanUtil;@Service

public class ProcessCheckServiceImpl implements ProcessCheckService {

private static final Logger log = LoggerFactory.getLogger(ProcessCheckServiceImpl.class);

private static final JsonMapper MAPPER = new JsonMapper(); @Override

public void process(ProcessDbModel model) { PrivateTransmitableUtil.set();

String[] paramArgs = BaseUtil.decodeZip(model.getParamArgs()); String[] paramTypes = BaseUtil.decodeZip(model.getParamTypes()); List> parameterTypes = new ArrayList<>(); List args = new ArrayList<>(); try {

for (int i = 0; i < paramTypes.length; i++) {

JavaType javaType = JacksonCanonicalUtil.constructFromCanonical(paramTypes[i]); parameterTypes.add(javaType.getRawClass());

args.add(MAPPER.readValue(paramArgs[i], javaType)); }

} catch (JsonProcessingException e) {

throw new RuntimeException(\"反序列化对象出错\ }

Object ret = ProcessBeanUtil.excuteBeanMethod( model.getTargetClassName(), model.getMethodName(),

parameterTypes.toArray(new Class[0]), args.toArray(new Object[0]) );

log.info(Objects.toString(ret)); }}

测试⽤的service

package com.proc.service;import com.proc.model.Person;import com.proc.model.Score;public interface TestService {

String testCheck(Person person, String team);

String testCheck2(Person person, String team);

String testCheckAsync(Person person, String team);

}

package com.proc.service.impl;import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import com.proc.bean.TestCheckPostProcess;import com.proc.config.Checked;import com.proc.model.Person;import com.proc.model.Score;

import com.proc.service.TestService;@Service

public class TestServiceImpl implements TestService {

private static final Logger log = LoggerFactory.getLogger(TestServiceImpl.class); //paramCanonical对应testCheck的参数类型 @Checked(

paramCanonical = {\"com.proc.model.Person\ postProcess = TestCheckPostProcess.class) @Override

public String testCheck(Person person, String team) { log.info(team + \">>>>\" + person); return \"target⽅法\"; }

@Checked( tag = \"A1\

paramCanonical = {\"com.proc.model.Person\ postProcess = TestCheckPostProcess.class) @Override

public String testCheck2(Person person, String team) { log.info(team + \">>2>>\" + person); return \"target2⽅法\"; }

@Async(\"processExecutor\") @Checked(

paramCanonical = {\"com.proc.model.Person\ postProcess = TestCheckPostProcess.class) @Override

public String testCheckAsync(Person person, String team) { log.info(team + \">>>>\" + person); return \"target⽅法\"; }}

审批⽤的controller

package com.proc.ctrl;import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import com.proc.model.ProcessDbModel;

import com.proc.service.ProcessCheckService;import com.proc.service.ProcessDbService;@RestController

public class ProcessCheckController {

private static final Logger log = LoggerFactory.getLogger(ProcessCheckController.class);

@Autowired

private ProcessDbService processDbService; @Autowired

private ProcessCheckService processCheckService;

@GetMapping(value = \"process\") public String process() {

ProcessDbModel processDbModel = processDbService.get(); log.info(processDbModel.toString());

processCheckService.process(processDbModel); return \"审批成功\"; }}

测试⽤的controller

package com.proc.ctrl;

import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import com.proc.model.CheckedParam;import com.proc.model.Person;import com.proc.model.Score;

import com.proc.service.TestService;

import com.proc.util.CheckedTransmitableUtil;@RestController

public class TestController { @Autowired

private TestService testService;

//模拟页⾯调⽤

@GetMapping(value = \"index\") public String testCheck() {

CheckedParam checkedParam = new CheckedParam(); checkedParam.setTagPageJs(\"01\"); List data = new ArrayList<>(); data.add(\"前端传进来的数据1\"); data.add(\"前端传进来的数据2\"); checkedParam.setData(data);

CheckedTransmitableUtil.set(checkedParam); Person person = new Person<>(); person.setName(\"⼀个⼈\"); person.setAge(\"18\"); person.setSex(\"1\");

person.setSalary(\"20000.00\"); person.setTestName(\"测试⼈\"); person.setWork(\"⼯作\");

Score score1 = new Score();

score1.setEnglish(new BigDecimal(\"12.4\")); score1.setLangue(new BigDecimal(\"7\")); score1.setMath(new BigDecimal(\"87.4\")); Score score2 = new Score();

score2.setEnglish(new BigDecimal(\"12.4\")); score2.setLangue(new BigDecimal(\"7\")); score2.setMath(new BigDecimal(\"87.4\")); List list = new ArrayList<>(); list.add(score1); list.add(score2);

person.setGrades(list);

testService.testCheck(person, \"team>>>>>>>>\"); return \"12345\"; }

//模拟其他渠道调⽤

@GetMapping(value = \"index2\") public String testCheck2() {

Person person = new Person<>(); person.setName(\"⼀个⼈\"); person.setAge(\"18\"); person.setSex(\"1\");

person.setSalary(\"20000.00\"); person.setTestName(\"测试⼈\"); person.setWork(\"⼯作\");

Score score1 = new Score();

score1.setEnglish(new BigDecimal(\"12.4\")); score1.setLangue(new BigDecimal(\"7\")); score1.setMath(new BigDecimal(\"87.4\")); Score score2 = new Score();

score2.setEnglish(new BigDecimal(\"12.4\")); score2.setLangue(new BigDecimal(\"7\")); score2.setMath(new BigDecimal(\"87.4\")); List list = new ArrayList<>(); list.add(score1); list.add(score2);

person.setGrades(list);

testService.testCheck2(person, \"team>>>2>>>>>\"); return \"12345\"; }

//模拟调⽤异步⽅法

@GetMapping(value = \"index3\") public String testCheckAsync() {

CheckedParam checkedParam = new CheckedParam(); checkedParam.setTagPageJs(\"01\"); List data = new ArrayList<>(); data.add(\"前端传进来的数据1\"); data.add(\"前端传进来的数据2\"); checkedParam.setData(data);

CheckedTransmitableUtil.set(checkedParam); Person person = new Person<>(); person.setName(\"⼀个⼈\"); person.setAge(\"18\"); person.setSex(\"1\");

person.setSalary(\"20000.00\"); person.setTestName(\"测试⼈\"); person.setWork(\"⼯作\");

Score score1 = new Score();

score1.setEnglish(new BigDecimal(\"12.4\")); score1.setLangue(new BigDecimal(\"7\")); score1.setMath(new BigDecimal(\"87.4\")); Score score2 = new Score();

score2.setEnglish(new BigDecimal(\"12.4\")); score2.setLangue(new BigDecimal(\"7\")); score2.setMath(new BigDecimal(\"87.4\")); List list = new ArrayList<>(); list.add(score1); list.add(score2);

person.setGrades(list);

testService.testCheckAsync(person, \"team>>>3>>>>>\"); return \"12345\"; }}

开启异步功能

package com.proc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsync

public class ProcessTestApplication { public static void main(String[] args) {

SpringApplication.run(ProcessTestApplication.class, args); }}

测试

到此这篇关于springboot注解Aspect的⽂章就介绍到这了,更多相关springboot注解Aspect内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- dfix.cn 版权所有 湘ICP备2024080961号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务