【问题标题】:Class cannot be cast to java.lang.reflect.ParameterizedType类不能转换为 java.lang.reflect.ParameterizedType
【发布时间】:2012-05-22 07:37:00
【问题描述】:

目前VariableService 在我的控制器中是@Autowired

我意识到我可以实现类ParameterizedType 来消除这个错误,但我担心我可能会走错方向。有没有更好的方法来做到这一点,还是我需要硬着头皮实施ParameterizedType的方法?

org.springframework.beans.factory.BeanCreationException:创建名为“contentController”的bean时出错:注入自动装配依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.fettergroup.cmt.service.VariableService com.fettergroup.cmt.web.ContentController.variableService;嵌套异常是 org.springframework.beans.factory.BeanCreationException:在 ServletContext 资源 [/WEB-INF/dispatcher-servlet.xml] 中定义名称为“variableService”的 bean 创建时出错:bean 的实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 bean 类 [com.fettergroup.cmt.service.VariableService]:构造函数抛出异常;嵌套异常是 java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

变量服务

public class VariableService extends EntityService {
    public VariableService () {
        super.setEntityRepository(new VariableRepository());
    }
}

实体服务

public abstract class EntityService<T> {

    public EntityRepository<T> entityRepository;

    public T create(T entity) {
        return entityRepository.create(entity);
    }

    public T update(T entity) {
        return entityRepository.update(entity);
    }

    public void delete(T entity) {
        entityRepository.delete(entity);
    }

    public void setEntityRepository(EntityRepository<T> entityRepository) {
        this.entityRepository = entityRepository;
    }
}

变量存储库

public class VariableRepository extends EntityRepository {

}

EntityRepository

@Repository
public abstract class EntityRepository<T> {

    //the equivalent of User.class
    protected Class<T> entityClass;

    @PersistenceContext(type= PersistenceContextType.TRANSACTION)
    public EntityManager entityManager;

    public EntityRepository () {
        //Get "T" and assign it to this.entityClass
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
    }

    /**
     * Create this entity
     * @param t
     * @return 
     */
    public T create(T t) {
        entityManager.persist(t);
        return t;
    }

    /**
     * Update this entity
     * @param t
     * @return 
     */
    public T update(T t) {
        return entityManager.merge(t);
    }

    /**
     * Delete this entity
     * @param entity 
     */
    public void delete(T t) {
        t = this.update(t);
        entityManager.remove(t);
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}

【问题讨论】:

    标签: java spring-mvc


    【解决方案1】:

    只是说,这是一个用于确定实体类型的非常糟糕的设计.. 您应该执行以下操作,而不是依靠反射来推断其类定义。 它不仅会消除该错误,而且总体上会更干净,并且级别较低,比反射更快(并不是说它真的会成为问题)。

    @Repository
    public abstract class EntityRepository<T>{
        protected Class<T> entityClass;
    
        public EntityRepository(Class<T> entityClass){
            this.entityClass = entityClass;
        }
    
        //...
    }
    
    
    public class UserEntityRepository extends EntityRepository<User>{
        public UserEntityRepository(){
            super(User.class);
        }
    }
    

    【讨论】:

    • 我只想说这是我用于数据访问层的设计方法。如果您有任何问题,请告诉我。
    • 可以用这种方式自动装配实体类吗?
    【解决方案2】:

    EntityRepository 不是 ParameterizedType 类型。此类仅扩展 ParameterizedType。如果 spring 通过 cglib 代理你的类,这也是可能的

    我们需要检查班级的家长

    public EntityRepository () {
        //Get "T" and assign it to this.entityClass
        Type genericSuperClass = getClass().getGenericSuperclass();
    
        ParameterizedType parametrizedType = null;
        while (parametrizedType == null) {
            if ((genericSuperClass instanceof ParameterizedType)) {
                parametrizedType = (ParameterizedType) genericSuperClass;
            } else {
                genericSuperClass = ((Class<?>) genericSuperClass).getGenericSuperclass();
            }
        }
    
        entityClass = (Class<T>) parametrizedType.getActualTypeArguments()[0];
    }
    

    【讨论】:

      【解决方案3】:

      您似乎误用了ParameterizedType。 在 EntityRepository 构造函数中,您应该使用类似以下的内容,并进行适当的检查。

      public EntityRepository () {
          //Get "T" and assign it to this.entityClass
          ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
          Type type = genericSuperclass.getActualTypeArguments()[0];
          if (type instanceof Class) {
            this.entityClass = (Class<T>) type;
          } else if (type instanceof ParameterizedType) {
            this.entityClass = (Class<T>) ((ParameterizedType)type).getRawType();
          }
      }
      

      不过,这个实现还远未完成,因为您还应该处理 GenericArrayType 值以及嵌套的 ParameterizedType

      【讨论】:

      • 我添加了你的内容并导入了java.lang.reflect.Type;type没有getRawType()的方法
      • 哦,我忘记了演员表。 type 的类型为 ParameterizedType,您必须将其转换为 ParameterizedType 才能调用 getRawType()
      【解决方案4】:

      @Repository注解需要从EntityRepository类中去掉才能解决问题。

      阅读本帖

      java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

      【讨论】:

        猜你喜欢
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        相关资源
        最近更新 更多