2013-05-30 63 views
1

我需要创建和春天有个异步过程,但是当我把@Async我的方法,我得到这个错误Spring @Async批注导致java.io.NotSerializableException?

java.io.NotSerializableException: org.springframework.aop.interceptor.AsyncExecutionInterceptor 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158) 

我有这样的例子,但它不工作:

@Autowired 
private IServicioClienteAsync servicioClienteAsync; 

public void prueba() { 
    //testAsync(); 
    servicioClienteAsync.crearCliente(); 
} 

@Service(value = "servicioClienteAsync") 
public class ServicioClienteAsync implements Serializable, IServicioClienteAsync { 

    @Autowired 
    private WServiceCliente wServiceCliente; 

    @Override 
    public void crearCliente() {   
     wServiceCliente.test("wiiii");   
    } 
} 

@Component 
public class WServiceCliente{ 

    @Async 
    public void test(String name) { 
     System.out.println("init "); 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("finish"); 
    } 
} 

回答

0

为了支持@Async注释的语义,Spring需要附加一个AsyncExecutionInterceptor来拦截对该方法的调用并指定要执行其代码的Executor。我猜AsyncExecutionInterceptor本身并不是简单的序列化,因为它持有一个Executor的引用,这个引用不太可能是可序列化的,否则开发人员根本就没有计划将其序列化。

典型Executor实现将引用一个或多个Thread实例在—和Thread执行(像其他任何包装的操作系统级手柄或类似的结构)是不可序列化有很好的理由;在这种情况下,即使AsyncExecutionInterceptor是可序列化的,序列化仍会沿着参考图进一步失败。

+0

好吧,但我需要这@Async你可以告诉我任何解决方案,我的控制器viewscope需要序列化和服务春天,你知道其他方式吗? – ggarridov

+0

您将无法在视图范围的bean中使用“@ Async”注释。你能将'@ Async'方法移动到会话或应用程序范围的bean吗?如果不是,则可以选择删除'@ Async'并只启动一个包含异步代码的新线程;这是通过返回'void'的方法简化的。 –

+0

好的,谢谢我会试试 – ggarridov

0

是否因为您的WServiceCliente不是Serializable而您的Serializable服务ServicioClienteAsync豆使用?

+0

不,我测试有和无序列化在我的班,但错误是为org.springframework.aop.interceptor.AsyncExecutionInterceptor – ggarridov

0

对于默认配置,我在执行程序bean的配置中使用@EnableAsync(mode = AdviceMode.ASPECTJ)并解决了问题。