2013-05-30 95 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)並解決了問題。