Spring - 不能强制使用CGLIB代理作为Classcast异常

时间:2011-04-10 08:08:24

标签: java spring proxy classcastexception cglib

这是让我疯狂的情景。

  1. 我有一个具有查找方法的类 - createOther()
  2. createOther应该创建一个Other类型的对象。其他实现OtherInterface,另外还有一个标记为@Async
  3. 的方法doSomething
  4. 由于Other实现了OtherInterface,Spring为我提供了一个我无法转换为其他的JDK代理。
  5. Spring文档建议使用<aop:config proxy-target-class="true"> - 但我是新手,使用它似乎没什么帮助。
  6. 问题:如何告诉Spring我需要一个针对Other类的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>
    

3 个答案:

答案 0 :(得分:1)

一切似乎都很好 - 这是告诉spring使用cglib代理的正确方法。实际上,默认情况下它会生成cglib代理的documentation states。唯一的要求是在类路径上使用cglib。确保你有cglib jar。

答案 1 :(得分:1)

task:annotation-driven元素应该支持自己的proxy-target-class属性,例如cglib代理需要设置为true,例如     

答案 2 :(得分:0)

Other oth = app.createOther();

这一行是问题所在。由于返回的对象实际上是一个代理,方法createOther()应返回代理将实现的OtherInterface

它试图将OtherInterface的代理版本强制转换为Other类并失败。