2011-04-10 31 views
4

這是推動我瘋狂的場景。春天 - 作爲CGLIB代理的Classcast例外不能被強制

  1. 我有一個具有一個查找方法的類 - (+)
  2. createOther應該創建其它類型的目的createOther。其他實現OtherInterface和另外有一個方法doSomething標記@Async
  3. 由於其他實現OtherInterface,Spring給了我一個JDK代理,我不能轉換爲其他。
  4. 春季文檔建議使用<aop:config proxy-target-class="true"> - 但我是一個新手,並使用它似乎沒有幫助。

問題:我如何告訴Spring我需要一個定位於其他類的CGLib代理?

以下代碼因類classcastexception失敗。

Exception in thread "main" java.lang.ClassCastException: $Proxy4 cannot be cast to scratch.Other 
at scratch.App$$EnhancerByCGLIB$$82d16307.createOther(<generated>) 
at scratch.App.main(App.java:19) 

App.java:

public class App { 
public Other createOther() { 
    throw new UnsupportedOperationException(); 
} 

public static void main(final String[] args) { 

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml"); 
    App app = (App) context.getBean("app"); 
    Other oth = app.createOther(); 
    oth.doSomething(); 
    System.out.println("Other created"); 
} 

}

** ** Other.java

public interface OtherInterface { 

} 

class Other implements OtherInterface { 

@Async 
public void doSomething() { 
    System.out.println("did something"); 
} 
} 

** ** appcontext.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:task="http://www.springframework.org/schema/task" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd 
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> 
<aop:config proxy-target-class="true"></aop:config> 
<bean name="app" class="scratch.App"> 
    <lookup-method bean="otherBean" name="createOther" /> 
</bean> 

<bean name="otherBean" class="scratch.Other" scope="prototype"> 
</bean> 
<task:executor id="workflowExecutorSvcPool" pool-size="5-50" 
    queue-capacity="1000" keep-alive="60" /> 
<task:annotation-driven executor="workflowExecutorSvcPool" /> 

</beans> 
+0

什麼是確切的異常消息。和堆棧跟蹤。 – Bozho 2011-04-10 08:29:07

+0

添加到帖子 – Raghu 2011-04-10 08:44:14

回答

1

一切似乎都很好 - 這是告訴spring使用cglib代理的正確方法。實際上,它將默認使用cglib代理服務器documentation states。唯一的要求是在您的類路徑中使用cglib。確保你有cglib jar。

+0

是的 - cglib-nodep在類路徑中。實際上,應用程序類是使用CGLIB進行分類的,如堆棧跟蹤中所示。 – Raghu 2011-04-10 08:58:30

+0

@拉胡 - 這是你正在使用的確切的「其他」類嗎?如果不是的話,你可以展示真實的課程嗎? – Bozho 2011-04-10 09:06:26

+0

是的 - 這是確切的「其他」類。我只是寫了應用程序和其他類來隔離isuse。 – Raghu 2011-04-11 00:47:54

1

task:annotation-driven元素應該支持它自己的proxy-target-class的屬性,將需要設置爲true,CGLIB代理,例如

0
Other oth = app.createOther(); 

此行是問題。由於返回的對象實際上是代理,所以方法createOther()應返回代理將執行的OtherInterface

它試圖將OtherInterface的代理版本轉換爲Other類並失敗。