Spring4.1新特性——异步调度和事件机制的异常处理

目录

Spring4.1新特性——综述

Spring4.1新特性——Spring核心部分及其他

Spring4.1新特性——Spring缓存框架增强

Spring4.1新特性——异步调用和事件机制的异常处理

Spring4.1新特性——数据库集成测试脚本初始化

Spring4.1新特性——Spring MVC增强

Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介

Spring4.1新特性——静态资源处理增强

Spring 4.1对异步调用提供了AsyncResult及SuccessCallback、FailureCallback、和异常处理的支持;对事件调度也提供了相应的异常处理器。

1、事件调度异常处理器

1.1、定义异常处理器:

Java代码   收藏代码
  1. public class MyErrorHandler implements ErrorHandler {  
  2.     @Override  
  3.     public void handleError(Throwable throwable) {  
  4.         System.out.println("事件失败了, error message : " + throwable.getMessage());  
  5.     }  
  6. }  

该异常处理器的一个缺点是不知道哪个事件出错了。

1.2、配置异常处理器:

Java代码   收藏代码
  1. <!-- 名字必须是applicationEventMulticaster和messageSource是一样的,默认找这个名字的对象 -->  
  2. <!-- 名字必须是applicationEventMulticaster,因为AbstractApplicationContext默认找个 -->  
  3. <!-- 如果找不到就new一个,但不是异步调用而是同步调用 -->  
  4. <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">  
  5.     <!-- 注入任务执行器 这样就实现了异步调用(缺点是全局的,要么全部异步,要么全部同步(删除这个属性即是同步))  -->  
  6.     <property name="taskExecutor" ref="executor"/>  
  7.     <property name="errorHandler" ref="myErrorHandler"/>  
  8. </bean>  
  9.   
  10. <bean id="myErrorHandler" class="com.sishuok.error.MyErrorHandler"/>  

当执行的ApplicationListener中有异常时会回调该ErrorHandler,但是从目前的回调实现来看,适合做日志记录,其他的无意义。本文是使用的代码基于《详解Spring事件驱动模型》。

2、异步调度异常处理器

在异步调度中也提供了相应的异常处理器进行捕获来记录异常:

Java代码   收藏代码
  1. public class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {  
  2.   
  3.     @Override  
  4.     public void handleUncaughtException(Throwable throwable, Method method, Object... args) {  
  5.         System.out.println("调用异步任务出错了, message : " + throwable.getMessage());  
  6.     }  
  7. }  

如上异常处理器的好处比事件机制的好处在于多了出错的位置和参数,可以根据这些信息进行相应的处理。

配置文件:

Java代码   收藏代码
  1. <bean id="asyncExceptionHandler" class="com.github.zhangkaitao.spring.service.MyAsyncExceptionHandler"/>  
  2. <task:annotation-driven exception-handler="asyncExceptionHandler" proxy-target-class="true" />  

  

异步Service:

Java代码   收藏代码
  1. @Service  
  2. @Async  
  3. public class AsyncService {  
  4.   
  5.     public void throwException() {  
  6.         throw new RuntimeException("error");  
  7.     }  
  8.   
  9.     public String asyncGet1() {  
  10.         return "123";  
  11.     }  
  12.   
  13.     //返回值必须是ListenableFuture/Future,因为是实现的问题(return ((AsyncListenableTaskExecutor) executor).submitListenable(task);)  
  14.     public ListenableFuture<String> asyncGet2() {  
  15.         return new AsyncResult<String>("123");  
  16.     }  
  17.   
  18. }  

当调用throwException时就会抛出异常并被异常处理器捕获到。

另外在之前文章中没有介绍异步方法的返回值,其返回值支持Future/ListenableFuture;然后调用者可以在此等待。Spring 4.1提供了AsyncResult(实现了ListenableFuture)用于返回异步结果。

ListenableFuture提供了新的回调(SuccessCallback和FailureCallback):

Java代码   收藏代码
  1. ListenableFuture<String> listenableFuture = asyncService.asyncGet2();  
  2. SuccessCallback<String> successCallback = new SuccessCallback<String>() {  
  3.     @Override  
  4.     public void onSuccess(String str) {  
  5.         System.out.println("异步回调成功了, return : " + str);  
  6.     }  
  7. };  
  8. FailureCallback failureCallback = new FailureCallback() {  
  9.     @Override  
  10.     public void onFailure(Throwable throwable) {  
  11.         System.out.println("异步回调失败了, exception message : " + throwable.getMessage());  
  12.     }  
  13. };  
  14.   
  15. listenableFuture.addCallback(successCallback, failureCallback);  
  16. Assert.assertEquals("123", listenableFuture.get());  

个人感觉事件机制中的异常处理考虑不周。

相关文章

详解Spring事件驱动模型

Spring4新特性

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

源码下载

https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-event

https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-async

 
评论
4 楼 supercwg 2014-08-19   引用
supercwg 写道
jinnianshilongnian 写道
supercwg 写道
涛 ge,还是要向你请教个shiro的问题,我是将shiro集成redis的,跑的是tomcat,我真搞不清楚shiro的session和 tomcat的session是什么关系?或者说如何理解两者的关系和差别?现在还要集成redis,shiro也可以实现cache将shiro session存到redis,那tomcat的session呢?我真被这个session搞晕了,求帮忙解决啊~~~

shiro的session可以基于web容器的或者独立的。因此看你需要了。如果用了shiro的session最好就不要再把数据放入到web容器的session中,这俩可能是独立变更的。会话就是在服务端保存用户信息的,存到哪怎么存你说了算。


哦,谢谢涛ge指点,我再仔细看看源码先

涛ge,另外还想请教个问题,就是我要实现个通用日志记录用户操作,直接在DAO层调用SecurityUtils.getSubject().getPrincipal()获取当前用户是否会存在问题
3 楼 supercwg 2014-08-19   引用
jinnianshilongnian 写道
supercwg 写道
涛 ge,还是要向你请教个shiro的问题,我是将shiro集成redis的,跑的是tomcat,我真搞不清楚shiro的session和 tomcat的session是什么关系?或者说如何理解两者的关系和差别?现在还要集成redis,shiro也可以实现cache将shiro session存到redis,那tomcat的session呢?我真被这个session搞晕了,求帮忙解决啊~~~

shiro的session可以基于web容器的或者独立的。因此看你需要了。如果用了shiro的session最好就不要再把数据放入到web容器的session中,这俩可能是独立变更的。会话就是在服务端保存用户信息的,存到哪怎么存你说了算。


哦,谢谢涛ge指点,我再仔细看看源码先
2 楼 jinnianshilongnian 2014-08-19   引用
supercwg 写道
涛 ge,还是要向你请教个shiro的问题,我是将shiro集成redis的,跑的是tomcat,我真搞不清楚shiro的session和 tomcat的session是什么关系?或者说如何理解两者的关系和差别?现在还要集成redis,shiro也可以实现cache将shiro session存到redis,那tomcat的session呢?我真被这个session搞晕了,求帮忙解决啊~~~

shiro的session可以基于web容器的或者独立的。因此看你需要了。如果用了shiro的session最好就不要再把数据放入到web容器的session中,这俩可能是独立变更的。会话就是在服务端保存用户信息的,存到哪怎么存你说了算。
1 楼 supercwg 2014-08-19   引用
涛ge,还是要向你请教个shiro的问题,我是将shiro集成redis的,跑的是 tomcat,我真搞不清楚shiro的session和tomcat的session是什么关系?或者说如何理解两者的关系和差别?现在还要集成 redis,shiro也可以实现cache将shiro session存到redis,那tomcat的session呢?我真被这个session搞晕了,求帮忙解决啊~~~

目录

Spring4.1新特性——综述

Spring4.1新特性——Spring核心部分及其他

Spring4.1新特性——Spring缓存框架增强

Spring4.1新特性——异步调用和事件机制的异常处理

Spring4.1新特性——数据库集成测试脚本初始化

Spring4.1新特性——Spring MVC增强

Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介

Spring4.1新特性——静态资源处理增强

Spring 4.1对异步调用提供了AsyncResult及SuccessCallback、FailureCallback、和异常处理的支持;对事件调度也提供了相应的异常处理器。

1、事件调度异常处理器

1.1、定义异常处理器:

Java代码   收藏代码
  1. public class MyErrorHandler implements ErrorHandler {  
  2.     @Override  
  3.     public void handleError(Throwable throwable) {  
  4.         System.out.println("事件失败了, error message : " + throwable.getMessage());  
  5.     }  
  6. }  

该异常处理器的一个缺点是不知道哪个事件出错了。

1.2、配置异常处理器:

Java代码   收藏代码
  1. <!-- 名字必须是applicationEventMulticaster和messageSource是一样的,默认找这个名字的对象 -->  
  2. <!-- 名字必须是applicationEventMulticaster,因为AbstractApplicationContext默认找个 -->  
  3. <!-- 如果找不到就new一个,但不是异步调用而是同步调用 -->  
  4. <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">  
  5.     <!-- 注入任务执行器 这样就实现了异步调用(缺点是全局的,要么全部异步,要么全部同步(删除这个属性即是同步))  -->  
  6.     <property name="taskExecutor" ref="executor"/>  
  7.     <property name="errorHandler" ref="myErrorHandler"/>  
  8. </bean>  
  9.   
  10. <bean id="myErrorHandler" class="com.sishuok.error.MyErrorHandler"/>  

当执行的ApplicationListener中有异常时会回调该ErrorHandler,但是从目前的回调实现来看,适合做日志记录,其他的无意义。本文是使用的代码基于《详解Spring事件驱动模型》。

2、异步调度异常处理器

在异步调度中也提供了相应的异常处理器进行捕获来记录异常:

Java代码   收藏代码
  1. public class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {  
  2.   
  3.     @Override  
  4.     public void handleUncaughtException(Throwable throwable, Method method, Object... args) {  
  5.         System.out.println("调用异步任务出错了, message : " + throwable.getMessage());  
  6.     }  
  7. }  

如上异常处理器的好处比事件机制的好处在于多了出错的位置和参数,可以根据这些信息进行相应的处理。

配置文件:

Java代码   收藏代码
  1. <bean id="asyncExceptionHandler" class="com.github.zhangkaitao.spring.service.MyAsyncExceptionHandler"/>  
  2. <task:annotation-driven exception-handler="asyncExceptionHandler" proxy-target-class="true" />  

  

异步Service:

Java代码   收藏代码
  1. @Service  
  2. @Async  
  3. public class AsyncService {  
  4.   
  5.     public void throwException() {  
  6.         throw new RuntimeException("error");  
  7.     }  
  8.   
  9.     public String asyncGet1() {  
  10.         return "123";  
  11.     }  
  12.   
  13.     //返回值必须是ListenableFuture/Future,因为是实现的问题(return ((AsyncListenableTaskExecutor) executor).submitListenable(task);)  
  14.     public ListenableFuture<String> asyncGet2() {  
  15.         return new AsyncResult<String>("123");  
  16.     }  
  17.   
  18. }  

当调用throwException时就会抛出异常并被异常处理器捕获到。

另外在之前文章中没有介绍异步方法的返回值,其返回值支持Future/ListenableFuture;然后调用者可以在此等待。Spring 4.1提供了AsyncResult(实现了ListenableFuture)用于返回异步结果。

ListenableFuture提供了新的回调(SuccessCallback和FailureCallback):

Java代码   收藏代码
  1. ListenableFuture<String> listenableFuture = asyncService.asyncGet2();  
  2. SuccessCallback<String> successCallback = new SuccessCallback<String>() {  
  3.     @Override  
  4.     public void onSuccess(String str) {  
  5.         System.out.println("异步回调成功了, return : " + str);  
  6.     }  
  7. };  
  8. FailureCallback failureCallback = new FailureCallback() {  
  9.     @Override  
  10.     public void onFailure(Throwable throwable) {  
  11.         System.out.println("异步回调失败了, exception message : " + throwable.getMessage());  
  12.     }  
  13. };  
  14.   
  15. listenableFuture.addCallback(successCallback, failureCallback);  
  16. Assert.assertEquals("123", listenableFuture.get());  

个人感觉事件机制中的异常处理考虑不周。

相关文章

详解Spring事件驱动模型

Spring4新特性

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

源码下载

https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-event

https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-async

猜你喜欢

转载自zzc1684.iteye.com/blog/2118883