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
实例(TypeVariableImpl
是 Type
).
的一个实现
如果 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
是必要的。
我有一个通用的 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
实例(TypeVariableImpl
是 Type
).
如果 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
是必要的。