【问题标题】:Spring get generic type classSpring获取泛型类型类
【发布时间】:2015-05-12 22:15:42
【问题描述】:

我知道这个问题经常被问到,但我无法找到解决方案。 如何在 Spring 注入的存储库中获取泛型类型类名称?

这是我的基础存储库

public interface UserRepository extends JpaRepository<User, Long>, IUserRepository<User>{
   User findByUsername(String username);
}

这是界面

public interface IUserRepository<T> {
   public List<T> findAllValidEtSiteAndStructure();
}

最后是实现

public class UserRepositoryImpl<T> implements IUserRepository<T> {

@PersistenceContext
private EntityManager em;

private Class< T > type;

@Override
public List<T> findAllValidEtSiteAndStructure() {
    final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication instanceof UserAuthentication) {
        final User currentUser = ((UserAuthentication) authentication).getDetails();
        return (List<T>) em.createQuery("FROM " + type.getName()+ " WHERE site=:site AND structure=:structure AND valid=:valid")
                .setParameter("site", currentUser.getInstallation().getSite())
                .setParameter("structure", currentUser.getInstallation().getStructure())
                .setParameter("valid", true)
                .getResultList();
    }
    return null;
}
}

我怎样才能得到 type.name? 提前致谢

【问题讨论】:

    标签: java spring generics


    【解决方案1】:

    考虑到您使用的是 Spring Framework,请使用下面的代码 sn-p,我已经测试过,它工作得很好:

    ResolvableType resolvableType = ResolvableType.forClass(UserRepository.class).as(JpaRepository.class);
    System.out.println(resolvableType.getGeneric(0));//User
    System.out.println(resolvableType.getGeneric(1));//Long
    

    【讨论】:

      【解决方案2】:

      您的问题的一般答案可以在文档中看到 -> http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations 在 Spring Data 存储库的自定义实现一章中

      但我认为在你的情况下这不应该是必要的。您应该可以通过以下方式做到这一点。

      public interface UserRepository extends JpaRepository<User, Long> {
      
         User findByUsername(String username);
      
         List<User> findByStructureAndSiteAndValid(Structure structure, Site site, boolean valid);
      }
      

      【讨论】:

        【解决方案3】:

        由于type erasure,基本上你无法获得泛型类型。

        我要做的是向UserRepositoryImpl 添加一个返回相关类型的抽象方法:

        public abstract Class getType();
        

        然后我会为 UserRepositoryImpl 创建特定实例,其类型在编译时已经知道。例如:

        public class StudentRepository extends UserRepositoryImpl<Student> {
          public Class getType() {
            return Student.class;
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-20
          • 2011-07-22
          • 2021-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多