Springboot怎么用Aop捕捉注解实现业务异步执行

其他教程   发布日期:2024年11月08日   浏览次数:246

这篇“Springboot怎么用Aop捕捉注解实现业务异步执行”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Springboot怎么用Aop捕捉注解实现业务异步执行”文章吧。

一、先说说线程的几种创建方式(简要列举)

1、继承Thread类,复写run方法:

  1. public class ExtendsThread extends Thread{
  2. @Override
  3. public void run() {
  4. try{
  5. System.out.println(Thread.currentThread().getName()+"执行");
  6. }catch (Exception e){
  7. }
  8. }
  9. public static void main(String[] args) {
  10. new Thread(new ExtendsThread()).start();
  11. }
  12. }

2、实现Runnable接口,重写run方法:

  1. public class ImplementsRunnable implements Runnable{
  2. @Override
  3. public void run() {
  4. try{
  5. System.out.println(Thread.currentThread().getName()+"执行");
  6. }catch (Exception e){
  7. }
  8. }
  9. public static void main(String[] args) {
  10. new Thread(new ImplementsRunnable()).start();
  11. //这里还可以使用匿名内部类的写法创建一个线程
  12. new Thread(new Runnable() {
  13. @Override
  14. public void run() {
  15. System.out.println(Thread.currentThread().getName()+"执行");
  16. }
  17. },"匿名内部类实现Runnable接口的线程");
  18. }
  19. }

3、实现Callable接口,使用FutureTask创建线程(可以获得返回值):

  1. public class CallableAndFuture implements Callable<String> {
  2. @Override
  3. public String call() throws Exception {
  4. Thread.sleep(3000);
  5. System.out.println(Thread.currentThread().getName()+"执行");
  6. return "success";
  7. }
  8. public static void main(String[] args) throws ExecutionException, InterruptedException {
  9. FutureTask<String> futureTask = new FutureTask<>(new CallableAndFuture());
  10. // futureTask.run(); 主线程执行call方法
  11. new Thread(futureTask).start();
  12. String result = futureTask.get();
  13. System.out.println(result);
  14. }
  15. }

4、使用线程池创建线程(这里利用提供的线程池框架Executors创建线程池):

  1. public class Executor {
  2. public static void main(String[] args) {
  3. ExecutorService executorService = Executors.newCachedThreadPool();
  4. executorService.execute(new Runnable() {
  5. @Override
  6. public void run() {
  7. System.out.println(Thread.currentThread().getName()+"执行");
  8. }
  9. });
  10. }
  11. }

二、再聊一聊spring自带的@Async注解实现异步任务的方法

其实很简单,就是在应用程序启动类上打@EnableAsync注解开启异步注解的使用,再在业务类的某个方法上打@Async即可。

  1. @SpringBootApplication
  2. @EnableAsync
  3. public class AopApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(AopApplication.class, args);
  6. }
  7. }

业务类方法(举例):

  1. @Async
  2. public void insertDb(){
  3. /*service code......*/
  4. System.out.println("2----->收到请求,写入数据库 ");
  5. }

三、那么就来设计一下怎么使用自定义的注解实现异步任务

首先我们写一个注解:

  1. @Target({ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface MyAsync {
  4. //规定value是异步开关
  5. boolean value() default false;
  6. }

我们让注解中的value的值定为布尔类型,从而根据它的真假来决定异步线程的创建。

我们将它打在业务类的方法上:

  1. @MyAsync(value = true)
  2. public void deleteDb(){
  3. /*service code......*/
  4. System.out.println("delete------>数据删除");
  5. }

然后我们利用AOP扫描这个注解:

  1. Aspect
  2. @Component
  3. public class AopUtils {
  4. @Around(value = "@annotation(com.example.aop.Aop异步.MyAsync)")
  5. public void listenMyAsync(ProceedingJoinPoint joinPoint) throws Throwable {
  6. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  7. Method method = signature.getMethod();
  8. MyAsync annotation = method.getAnnotation(MyAsync.class);
  9. boolean value = annotation.value();
  10. if (value)
  11. new Thread(new Runnable() {
  12. @SneakyThrows
  13. @Override
  14. public void run() {
  15. joinPoint.proceed();
  16. }
  17. }).start();
  18. else
  19. joinPoint.proceed();
  20. }
  21. }

我们可以看到利用Around寻找执行的线程中某个含有注解的方法栈,捕捉到之后就可以获得对应的连接点对象了。

利用可通过连接点对象ProcedJoinPoint的getSignture方法获取签名,可以将签名强制转化成方法签名MethdSignture类型,从而利用该类型的getMethod方法获取方法本身,接下来就可以获取方法的注解,利用注解的属性直接获取value的真假,从而决定方法通过的方式是同步的还是异步的。(源码利用到反射机制)。

以上就是Springboot怎么用Aop捕捉注解实现业务异步执行的详细内容,更多关于Springboot怎么用Aop捕捉注解实现业务异步执行的资料请关注九品源码其它相关文章!