Spring 依赖注入通用服务 class

Spring dependency injection generic service class

我有一个通用的 dao class 并且我正在尝试使用 spring 依赖注入但是我有以下错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BaseDao' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.abgc.fab.dao.BaseDao]: Constructor threw exception; nested exception is java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

我的applicationContext.xml文件

<bean id="BaseDao" class="com.abgc.fab.dao.BaseDao">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

我的 basedao class :

public class BaseDao<TEntity> extends CommonDao<TEntity> implements IBaseDao<TEntity> {

}

 public abstract class CommonDao<TEntity> extends FabObject implements ICommonDao<TEntity> { 
       public CommonDao() { 
               Type t = getClass().getGenericSuperclass();
               ParameterizedType pt = (ParameterizedType) t;           
                this.classEntity = (Class<TEntity>) pt.getActualTypeArguments()[0]; 
      }

有什么帮助吗?

检查注解@Entity、@Service 等。也许您遗漏了什么。所以DAOclass无法调用POJOClass,bean也无法初始化。

TEntity 是实际的 class 还是您的类型参数?

在我看来,TEntity 只是您的类型参数的名称,我认为它不起作用。

你需要像

这样的东西
class ConcreteNominationHibernateDAO
    extends BaseDao<ConcreteNominationSubclass> {...}

根据 javadoc,ParameterizedType.getActualTypeArguments returns Type[]Type 不一定是 Class,因此转换为 Class 是不安全的。

根据 Piotr Findeisen 的回答 here

The expression

getClass().getGenericSuperclass()).getActualTypeArguments()[0]

指代入AbstractHibernateDAO第一个类型参数的值(在AbstractHibernateDAO.java中用T表示)。 subclassNominationHibernateDAO代入的类型还是不具体,是T extends Nomination,肯定不是java.lang.Class实例,而是Type实例(TypeVariableImplType).

的一个实现

如果 NominationHibernateDAO 是这样声明的:

class NominationHibernateDAO extends AbstractHibernateDAO<Nomination, Integer> { ...

那么 AbstractHibernateDAO 构造函数魔法就会起作用。或者,您可以(或者您甚至应该?)实例化 NominationHibernateDAO 的子 class 声明如下:

class ConcreteNominationHibernateDAO
        extends NominationHibernateDAO<ConcreteNominationSubclass> { ...

new NominationHibernateDAO<ConcreteNominationSubclass>() {}

同样,这不会触发问题。

您确定 NominationHibernateDAO class 用作 Spring bean 吗?

如果层次结构很深,您需要使用类似 TypeTools:

的东西
class DeviceDao extends BaseDao<Device> {}

Class<?> entityType = TypeResolver.resolveRawArgument(IBaseDao.clas, DeviceDao.class);
assert entityType == Device.class;

注意:一如既往,类型参数只有在类型定义中捕获时才能在运行时解析。所以子类化 BaseDao 是必要的。