Spring@async方法如何添加注解实现异步调用

介绍

小编给大家分享一下Spring@async方法如何添加注解实现异步调用,希望大家阅读完这篇文章之后都有所收获、下面让我们一起去探讨吧!

这篇文章主要介绍了春天@async方法如何添加注解实现异步调用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在我们使用弹簧框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率。今天我们来探讨下春天是如何完成这个功能的。

春在扫描bean的时候会扫描方法上是否包含@async的注解,如果包含的,春天会为这个bean动态的生成一个子类,我们称之为代理类(?),代理类是继承我们所写的豆的,然后把代理类注入进的来,那此时,在执行此方法的时候,会到代理类中,代理类判断了此方法需要异步执行,就不会调用父类(我们原本写的bean)的对应方法.spring自己维护了一个队列,他会把需要执行的方法,放入队列中,等待线程池去读取这个队列,完成方法的执行,从而完成了异步的功能。

我们可以关注到再配置任务的时候,是有参数让我们配置线程池的数量的,因为这种实现方法,所以在同一个类中的方法调用,添加@async注解是失效的!,原因是当你在同一个类中的时候,方法调用是在类体内执行的,弹簧无法截获这个方法调用。

那在深入一步,春天为我们提供了AOP,面向切面的功能。他的原理和异步注解的原理是类似的,春天在启动容器的时候,会扫描切面所定义的类。在这些类被注入的时候,所注入的也是代理类,当你调用这些方法的时候,本质上是调用的代理类。通过代理类再去执行父类相对应的方法,那春天只需要在调用之前和之后执行某段代码就完成了AOP的实现了!

那最后我们还有一个问题,春天是如何动态的生成某一个类的子类的?代理类?

简单介绍:

春为任务调度与异步方法执行提供了注解支持。通过在方法上设置@async注解,可使得方法被异步调用。也就是说调用者会在调用时立即返回,而被调用方法的实际执行是交给春天的TaskExecutor来完成。

开启@async注解:

& lt;任务:注解驱动的遗嘱执行人=癮nnotationExecutor"/祝辞;& lt; !——支持@Async注解——祝辞& lt;任务:执行程序id=癮nnotationExecutor"池的大??0“/祝辞

同时加入& lt;上下文:component-scan/祝辞扫描注解。

为了比较,先来一个同步调用:

@Componentpublic类TestAsyncBean {, public void sayHello4()抛出InterruptedException {,线程。睡眠(2 * 1000);//网络连接中……消息发送中……,,System.out.println(“我爱你啊!“);}

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration({“类路径:/applicationContext.xml"})公开课TestAsync {@Test大敌;公共空test_sayHello4()抛出InterruptedException, ExecutionException {,,System.out.println(“你不爱我了么?“);,,testAsyncBean.sayHello4 ();,,System.out.println(“回的这么慢,你肯定不爱我了,我们还是分手吧…“);,线程。睡眠(3 * 1000);//不让主进程过早结束,}}

输出结果:

你不爱我了么?我爱你啊!回的这么慢,你肯定不爱我了,我们还是分手吧…

同步调用会按代码顺序依次进行下去,如果哪里需要等待,那么就阻塞在那里,不再向下继续进行。

使用@Async的异步调用:

@Componentpublic类TestAsyncBean {@Async大敌;公共空sayHello3()抛出InterruptedException {,线程。睡眠(2 * 1000);//网络连接中……消息发送中……,,System.out.println(“我爱你啊!“);,}}

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration({“类路径:/applicationContext.xml"})公开课TestAsync {@ autowired大敌;私人TestAsyncBean TestAsyncBean;@Test大敌;公共空test_sayHello3()抛出InterruptedException, ExecutionException {,,System.out.println(“你不爱我了么?“);,,testAsyncBean.sayHello3 ();,,System.out.println(“你竟无话可说,我们分手吧…“);,线程。睡眠(3 * 1000);//不让主进程过早结束,}}

输出结果:

你不爱我了么?你竟无话可说,我们分手吧……我爱你啊!

异步调用,通过开启新的线程来执行调用的方法,不影响主线程。异步方法实际的执行交给了春天的TaskExecutor来完成。

上面这种方式是没有返回值的,下面尝试有返回值的异步调用:

@Componentpublic类TestAsyncBean {@Async大敌;公共字符串sayHello2()抛出InterruptedException {,线程。睡眠(2 * 1000);//网络连接中……消息发送中……,,返回“我爱你啊!“;//调用方调用后会立即返回,所以返回零,}}

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration({“类路径:/applicationContext.xml"})公开课TestAsync {@ autowired大敌;私人TestAsyncBean TestAsyncBean;@Test大敌;公共空test_sayHello2()抛出InterruptedException, ExecutionException {,,System.out.println(“你不爱我了么?“);,,System.out.println (testAsyncBean.sayHello2 ());,,System.out.println(“你说的啥?我们还是分手吧…“);,线程。睡眠(3 * 1000);//不让主进程过早结束,}}

Spring@async方法如何添加注解实现异步调用