我想问一下异常的根本原因

Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to  
java.lang.reflect.ParameterizedType

当我们让Spring为类生成代理时(即在事务管理器上设置proxy-target-class="true" ,这会在Spring中发生:

<tx:annotation-driven transaction-manager="transactionManager" 
proxy-target-class="true"/>

并且要代理的类是参数化的类,即

public class SomeDAOImpl<SomeEntity> implements SomeDAO ...

例如,可以在以下问题中阅读全文: 抽象DAO模式和Spring的“代理不能转换为...”问题!

问题: Spring为什么不能代理此类? 是因为它使用了旧的代码生成库? 因为类型擦除? 如果SomeDAOImpl不是通用类,它将成功(我检查过)。

请不要这样回答:“您应该代理接口,而不是类”。 我知道。

===============>>#1 票数:5 已采纳

这看起来像一个Spring / CGLIB问题,但问题实际上出在您的构造函数中! 我猜您正在尝试获取参数类型,以便可以将其提供给实体管理器(或您要使用的任何持久性框架)。 我还猜到这样做是要调用getGenericSuperclass()并将其强制转换为ParameterizedType?

方法的行为方式取决于类。 事实证明,并非所有Class对象都实现ParameterizedType接口(我同意,这很奇怪)。 生成的CGLIB代理不保留泛型信息。 看起来像:

public class SomeDAOImplProxy extends SomeDAOImpl

我实际上不知道为什么CGLIB代理不保留通用名称,因为CGLIB代理的细节非常复杂。 这样做根本不可能。 也有可能这样做并不是他们的优先考虑。

这是一个简单的实验,它使Spring和CGLIB脱颖而出,但仍然出现该错误。

public static void main(String [] args) {
    List<Object> fooList = new ArrayList<Object>();
    String fooString = "";
    System.out.println((ParameterizedType)fooList.getClass().getGenericSuperclass());
    System.out.println((ParameterizedType)fooString.getClass().getGenericSuperclass());
}

===============>>#2 票数:4

由于CGLIB子类化了您的类以生成代理,因此您必须获取超类的通用超类以获取ParameterizedType

public class MyCglibProxiedBean<T> {

    private final Class<T> paramClass;

    public MyCglibProxiedBean() {
        Type genericSuperClass = getClass().getGenericSuperclass();

        // Get the generic super class of the super class if it's a cglib proxy
        if (getClass().getName().contains("$$EnhancerByCGLIB$$")) {
            genericSuperClass = getClass().getSuperclass().getGenericSuperclass();
        }

        this.paramClass = (Class<T>) ((ParameterizedType) genericSuperClass).getActualTypeArguments()[0];
    }
}

===============>>#3 票数:1

我们使用的解决方案与James的答案类似,但恕我直言有点笼统:

Type genericSuperClass = repositoryClass.getGenericSuperclass();
ParameterizedType parametrizedType;
if (genericSuperClass instanceof ParameterizedType) { // class
    parametrizedType = (ParameterizedType) genericSuperClass;
} else if (genericSuperClass instanceof Class) { // in case of CGLIB proxy
    parametrizedType = (ParameterizedType) ((Class<?>) genericSuperClass).getGenericSuperclass();
} else {
    throw new IllegalStateException("class " + repositoryClass + " is not subtype of ParametrizedType.");
}

@SuppressWarnings("unchecked")
Class<T> entityClass = (Class<T>) parametrizedType.getActualTypeArguments()[0];
return entityClass;

===============>>#4 票数:0

我设法用以下代码解决了这个问题:

Type t = getClass();
do {
  t = ((Class<T>) t).getGenericSuperclass();
} while (!(t instanceof ParameterizedType));
ParameterizedType pt = (ParameterizedType) t;
actualGenericType = (Class<T>) pt.getActualTypeArguments()[0];

我认为这是一个更干净的解决方案,因为它不使用CGLIB的内部结构。

  ask by MaDa translate from so

未解决问题?本站智能推荐:

3回复

春季-无法强制使用CGLIB代理作为Classcast异常

这是使我发疯的情况。 我有一个具有查找方法的类-createOther() createOther应该创建其他类型的对象。 其他工具OtherInterface,另外还有一个方法doSomething,标记为@Async 由于Other实现了OtherInterfac
2回复

Spring MVC中的Integer的CGLib代理(最终类)

我需要这样的用法: 对于每个请求,我想将userId注入DemoController,但是由于是没有空构造函数的最终类,因此无法注入它。 在这种情况下,最佳做法是什么? 具有请求范围的服务可以吗?
1回复

春季变化cglib

我在我的应用程序中使用Spring,当我们有一些不实现任何接口的类时,Spring将使用“ cglib”进行代理。 我可以在Spring中将cglib更改为其他lib吗? 如果是,我该怎么办? 谢谢! [编辑]嗨,我想这样做是因为当我使用CGLIB时PermGen出现问题,当
1回复

Spring-cglib代理在类层次结构中的行为

我有2节课 上面的system.out打印null。我哪里出错了,请帮忙。 cglib是这样工作的吗?
1回复

我怎样才能让我的CGLIB代理类与Spring框架的ReflectionUtils工作?

我有一个CGLIB代理类,因为IMPL同时使用@Repository @Transactional注解。 我想使用Spring的反射utils的设置字段值嘲讽出的领域之一。 但是,当反射utils的不能在我的班级中找到字段。 我该如何工作? 于是我可以模拟出现场(合作者)。
1回复

AbstractEndpointExceptionResolver,cglib代理,空字段

我有WebService。 我通过扩展SoapFaultMappingExceptionResolver编写了自己的异常解析器。 每当我尝试引发异常时,我都会得到NPE: 发生在网上: 因为记录器为空。 据我了解,在调试过程中,发生这种情况是因为CGLIB正在代理我的扩
1回复

避免spring cglib代理问题

在spring中使用cglib代理会导致: a)构造函数的双重调用 b)不允许拦截从另一个方法调用的方法 但为什么spring创建一个bean然后代理? 是否可以动态生成扩展指定bean类的类,然后只调用一次构造函数? 这将解决a)和b)公共和受保护的方法。 我错过了什么
1回复

Spring交易和CGLIB代理

我正在尝试在Spring 3.0.7容器内的事务中处理数据源更新。 我的DAO类未实现接口,并充当由另一个bean @Component @Autowired的具体类。 这是布局: 我的应用程序上下文具有以下事务设置(这是测试单元bean配置,因为我通过junit / Spring测
1回复

CGLib代理,无空构造函数

让我们考虑一下我有一些具有B类属性的A类。 不,我有CGLIB代理: 现在,当我将CGLib用于ClassA时,代理将创建ClassA实例。 我的问题是如何将classB参数传递给此代理,因为据我了解,CGLib将为ClassA运行空的构造函数?
1回复

有关Cglib代理MethodInterceptor回调参数的问题

当使用Spring Cglib代理时,我们需要实现MethodInterceptor回调,我对此回调有一些问题。 为了更清楚一点,让我们使用一个简单的示例。 这是我的目标类MyPlay.java public class MyPlay { public void play() { Sy