Spring - исключение Classcast, поскольку прокси-сервер CGLIB не может быть принудительно установлен - PullRequest
4 голосов
/ 10 апреля 2011

Вот сценарий, который сводит меня с ума.

  1. У меня есть класс, у которого есть метод поиска - createOther ()
  2. createOther должен создать объект типа Other.Другие реализуют OtherInterface и, кроме того, имеют метод doSomething, помеченный @ Async
  3. . Поскольку другие реализуют OtherInterface, Spring предоставляет мне JDK-прокси, который я не могу разыграть как Other.
  4. Документы Spring предлагают использовать <aop:config proxy-target-class="true"> - но я новичок в этом, и использование этого, похоже, не помогает.

Вопрос: как мне сказать Spring, что мне нужен прокси-сервер CGLib, предназначенный для класса Other?

Приведенный ниже код завершается с ошибкой classcastex.

    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 ]

1 голос
/ 11 апреля 2011

Элемент task:annotation-driven должен поддерживать собственный атрибут proxy-target-class, который должен быть установлен в true для прокси-серверов cglib, например

1 голос
/ 10 апреля 2011

Кажется, все в порядке - это правильный способ указать Spring использовать прокси cglib. Фактически, в документации указано , что по умолчанию она будет создавать прокси-серверы cglib. Единственное требование - иметь cglib на вашем пути к классам. Убедитесь, что у вас есть банка cglib.

0 голосов
/ 10 сентября 2014
Other oth = app.createOther();

Эта строка является проблемой.Поскольку возвращаемый объект на самом деле является прокси, метод createOther() должен возвращать OtherInterface, который прокси будет реализовывать

Это попытка привести прокси-версию OtherInterface к классу Other и ошибка.

...