2011-04-10 25 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类并失败。