??? spring 在掃描bean的時(shí)候會(huì)掃描方法上是否包含@async的注解,如果包含的,spring會(huì)為這個(gè)bean動(dòng)態(tài)的生成一個(gè)子類,我們稱之為代理類(?),代理類是繼承我們所寫的bean的,然后把代理類注入進(jìn)來(lái),那此時(shí),在執(zhí)行此方法的時(shí)候,會(huì)到代理類中,代理類判斷了此方法需要異步執(zhí)行,就不會(huì)調(diào)用父類(我們?cè)緦懙腷ean)的對(duì)應(yīng)方法。spring自己維護(hù)了一個(gè)隊(duì)列,他會(huì)把需要執(zhí)行的方法,放入隊(duì)列中,等待線程池去讀取這個(gè)隊(duì)列,完成方法的執(zhí)行,從而完成了異步的功能。我們可以關(guān)注到再配置task的時(shí)候,是有參數(shù)讓我們配置線程池的數(shù)量的。 因?yàn)檫@種實(shí)現(xiàn)方法,所以在同一個(gè)類中的方法調(diào)用,添加@async注解是失效的! ,原因是當(dāng)你在同一個(gè)類中的時(shí)候,方法調(diào)用是在類體內(nèi)執(zhí)行的,spring無(wú)法截獲這個(gè)方法調(diào)用。?
??? 那在深入一步,spring為我們提供了AOP,面向切面的功能。他的原理和異步注解的原理是類似的,spring在啟動(dòng)容器的時(shí)候,會(huì)掃描切面所定義的類。在這些類被注入的時(shí)候,所注入的也是代理類,當(dāng)你調(diào)用這些方法的時(shí)候,本質(zhì)上是調(diào)用的代理類。通過(guò)代理類再去執(zhí)行父類相對(duì)應(yīng)的方法,那spring只需要在調(diào)用之前和之后執(zhí)行某段代碼就完成了AOP的實(shí)現(xiàn)了!?
?? 那最后我們還有一個(gè)問(wèn)題,spring是如何動(dòng)態(tài)的生成某一個(gè)類的子類的?代理類??
?? 生成代理類可以通過(guò)jdk 和 CGLIB 兩種方式生成.具體的可以?
?? 參考 1.代理類說(shuō)明: http://wenku.baidu.com/link?url=YpU3CNXsyLivMCnpILQ1qQc8PcKuqRrqZd1X8hPNQa9QuBFmbpCugSdjkXlY2L_ey4rUxM7TlwHeAatL65e664h_W8n0IKgTP1vFU5wacrm
??????? 2.CGLIB和JDK代理類的區(qū)別: http://www.blogjava.net/hello-yun/archive/2011/11/09/363359.html ?
這里就不詳細(xì)說(shuō)明了?
假如在網(wǎng)站的用戶注冊(cè)后,需要發(fā)送郵件,然后用戶得到郵件確認(rèn)后才能繼續(xù)其他工作;?
假設(shè)發(fā)送是一個(gè)很耗費(fèi)時(shí)間的過(guò)程,因此需要異步。?
1 namespace要注意,加上task?
??
- <?xml?version=” 1.0 ″?encoding=”UTF- 8 ″?>??
- ??
- <beans?xmlns=”http: //www.springframework.org/schema/beans”?xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” ??
- xmlns:p=”http: //www.springframework.org/schema/p”?xmlns:context=”http://www.springframework.org/schema/context” ??
- xsi:schemaLocation=”??
- http: //www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ??
- http: //www.springframework.org/schema/context?http://www.springframework.org/schema/context/spring-context-3.0.xsd ??
- http: //www.springframework.org/schema/task?http://www.springframework.org/schema/task/spring-task-3.0.xsd”> ??
- ??
- <context:component-scan?base- package =”cs”/>??
- ??
- </beans>??
2 RegularService.java 注冊(cè)類?
??
- ? import ?org.springframework.beans.factory.annotation.Autowired;??
- import ?org.springframework.stereotype.Service;??
- ??
- import ?cs.async.MailUtility;??
- ??
- @Service ??
- public ? class ?RegularService?{??
- ??
- @Autowired ??
- private ?MailUtility?mailUtility?;??
- ??
- public ? void ?registerUser(String?userName){??
- ??
- System.out.println(”?User?registration? for ??“+userName?+”?complete”);??
- ??
- mailUtility.sendMail(userName);??
- ??
- System.out.println(”?注冊(cè)完成,郵件稍后發(fā)送“);??
- }??
- ??
- }??
- ??
- 3 ?發(fā)送郵件的工具類??
- import ?org.springframework.scheduling.annotation.Async;??
- import ?org.springframework.stereotype.Component;??
- ??
- @Component ??
- public ? class ?MailUtility?{??
- ??
- @Async ??
- public ? void ?sendMail(String?name){??
- ??
- System.out.println(”?在做發(fā)送準(zhǔn)備工作中??“);??
- ??
- try ?{??
- Thread.sleep( 5000 );??
- ??
- }? catch ?(InterruptedException?e)?{??
- ??
- e.printStackTrace();??
- }??
- ??
- System.out.println(”?異步發(fā)送完畢“);??
- ??
- }??
- ??
- }??
- ?
- ?
- 4 ?最后在applicationContext.xml中加入:??
- <?xml?version=” 1.0 ″?encoding=”UTF- 8 ″?>??
- ??
- <beans?xmlns=”http: //www.springframework.org/schema/beans”?xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” ??
- xmlns:p=”http: //www.springframework.org/schema/p”?xmlns:context=”http://www.springframework.org/schema/context” ??
- xmlns:task=”http: //www.springframework.org/schema/task” ??
- xsi:schemaLocation=”??
- http: //www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ??
- http: //www.springframework.org/schema/context?http://www.springframework.org/schema/context/spring-context-3.0.xsd ??
- http: //www.springframework.org/schema/task?http://www.springframework.org/schema/task/spring-task-3.0.xsd“> ??
- ??
- <context:component-scan?base- package =”cs”/>??
- ??
- <task:annotation-driven/>??
- ??
- </beans>??
- ? ?就是<task:annotation-driven/>這個(gè)一定不能少喔。 ?
- ?
- 5 ?運(yùn)行:??
- ? User?registration? for ??tom?complete??
- ? 注冊(cè)完成,郵件稍后發(fā)送??
- ? 在做發(fā)送準(zhǔn)備工作中??
- ? 異步發(fā)送完畢??
- ?
- ? 6 ?有的時(shí)候,要從異步中返回值,這個(gè)時(shí)候,spring會(huì)返回一個(gè)java.util.concurrent.Future對(duì)象,要調(diào)用其中的get方法,比如??
- @Async ??
- public ?Future<Balance>?findBalanceAsync( final ?Account?account)?{??
- ????Balance?balance?=?accountRepository.findBalance(account);??
- ???? return ? new ?AsyncResult<Balance>(balance);??
- }??
- ??
- Balance?balance?=?future.get();??
- ??
-
Spring3中加強(qiáng)了注解的使用,其中計(jì)劃任務(wù)也得到了增強(qiáng),現(xiàn)在創(chuàng)建一個(gè)計(jì)劃任務(wù)只需要 兩步 就完成了:
- 創(chuàng)建一個(gè)Java類,添加一個(gè)無(wú)參無(wú)返回值的方法,在方法上用@Scheduled注解修飾一下;
- 在Spring配置文件中添加三個(gè)<task:**** />節(jié)點(diǎn);
最后說(shuō)明一下,第一步創(chuàng)建的Java類要成為Spring可管理的Bean,可以直接寫在XML里,也可以@Component一下
?
示例如下
計(jì)劃任務(wù)類:
- /** ?
- ?*?com.zywang.spring.task.SpringTaskDemo.java ?
- ?*?@author?ZYWANG?2011-3-9 ?
- ?*/ ??
- package ?com.zywang.spring.task;??
- ??
- import ?org.springframework.scheduling.annotation.Scheduled;??
- import ?org.springframework.stereotype.Component;??
- ??
- /** ?
- ?*?Spring3?@Scheduled?演示 ?
- ?*?@author?ZYWANG?2011-3-9 ?
- ?*/ ??
- @Component ??
- public ? class ?SpringTaskDemo?{??
- ??
- ???? @Scheduled (fixedDelay?=? 5000 )??
- ???? void ?doSomethingWithDelay(){??
- ????????System.out.println( "I'm?doing?with?delay?now!" );??
- ????}??
- ??????
- ???? @Scheduled (fixedRate?=? 5000 )??
- ???? void ?doSomethingWithRate(){??
- ????????System.out.println( "I'm?doing?with?rate?now!" );??
- ????}??
- ??????
- ???? @Scheduled (cron?=? "0/5?*?*?*?*?*" )??
- ???? void ?doSomethingWith(){??
- ????????System.out.println( "I'm?doing?with?cron?now!" );??
- ????}??
- }??
Spring配置文件:
- <? xml ? version = "1.0" ? encoding = "UTF-8" ?> ??
- < beans ? xmlns = "http://www.springframework.org/schema/beans" ??
- ???? xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" ? xmlns:task = "http://www.springframework.org/schema/task" ??
- ???? xsi:schemaLocation ="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd??
- ????????http://www.springframework.org/schema/task?http://www.springframework.org/schema/task/spring-task-3.0.xsd" > ??
- ???? <!--?Enables?the?Spring?Task?@Scheduled?programming?model?--> ??
- ???? < task:executor ? id = "executor" ? pool-size = "5" ? /> ??
- ???? < task:scheduler ? id = "scheduler" ? pool-size = "10" ? /> ??
- ???? < task:annotation-driven ? executor = "executor" ? scheduler = "scheduler" ? /> ??
- </ beans > ??
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
