Spring Boot2.0之@Async实现异步调用

Posted toov5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot2.0之@Async实现异步调用相关的知识,希望对你有一定的参考价值。

 补充一个知识点:

lombok底层原理使用的是: 字节码技术ASM修改字节码文件,生成比如类似于get() set( )方法

一定要在开发工具安装 在编译时候修改字节码文件(底层使用字节码技术),线上环境使用编译好的文件

 

下面我们学习 Spring Boot 异步调用技术:

启动加上@EnableAsync ,需要执行异步方法上加入    @Async

在方法上加上@Async之后 底层使用多线程技术

在底层实际上是帮助创建线程了 

首先创建类:MembrController

  package com.toov5.jsp;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import com.toov5.service.MemberService;

import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class MemberController {
  @Autowired
  private MemberService memberService;
  
    public String addMemberAndEmail(){
       log.info("1");
       String result = memberService.addMemberAndEmail();
       log.info("4");
       return result;
    }
    
}

MemberService

package com.toov5.service;

import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class MemberService {
    //添加用户时候发送邮件
    public String addMemberAndEmail(){
        log.info("2");  
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            // TODO: handle exception
        }
        log.info("3");
        return "toov5";

    }
    
    
}

我们做个分析:

这个项目是没有开线程的情况下的,代码从上往下同步进行的,log输出结果就是1 2 3 return返回结果  4 然后返回结果 

看结果:

 

先输出1 2  然后 五秒 后 3  4  效果是同步的

下面隆重接受一个注解

@Async 相当于这个方法重新开辟了新的线程去执行

 

然后启动类一定要加上启动的注解!!!@EnableAsync

 

 加上 @EnableAsync看看指定的包里面  有哪些加了@Asyn注解 加了的在运行时候通过AOP技术,创建线程去执行

执行结果:

controller的代码这样:

  package com.toov5.jsp;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.toov5.service.MemberService;

import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class MemberController {
  @Autowired
  private MemberService memberService;
    
    @RequestMapping("/addMemberAndEmail")
    public String addMemberAndEmail(){
       log.info("1");
       String result = memberService.addMemberAndEmail();
       log.info("4");
       return "result"+result;
    }
    
}

结果:

 

 结果值是没有拿到 主线程就后已经结束了哈 所以为 null

 

原理思路:

使用AOP技术,在运行时候 创建单独线程进行执行 

可以这么代替:

package com.toov5.service;


import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class MemberService {
    //添加用户时候发送邮件
//	@Async
//	public String addMemberAndEmail(){
//		log.info("2");  
//		try {
//			Thread.sleep(5000);
//		} catch (Exception e) {
//			// TODO: handle exception
//		}
//		log.info("3");
//		return "toov5";
//
//	}

	public String addMemberAndEmail(){
		
	   new Thread(new Runnable() {
		
		public void run() {
		
			log.info("2");  
			try {
				Thread.sleep(5000);
			} catch (Exception e) {
				// TODO: handle exception
			}
			log.info("3");
//			return "toov5";  //这里应该用从callable  有返回值 或者future模式
				
		}
	}).start();
	
	   return "toov5";  //将就下 返回值由于是用的runnable写的嘛 先这样迁就下
		
	}
	
	

		
}

 效果:

 

 

小伙伴是不是很好玩呀?赶紧尝试一下吧~

 

以上是关于Spring Boot2.0之@Async实现异步调用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot2.0之整合Redis

Spring Boot2.0之 监控管理

Spring Boot2.0之 jar打包方式

Spring Boot2.0之性能优化

SpringBoot之@Async异步调用

Spring Boot2.0之 原理—创建内置Tomcat容器