You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Spring实体传递给泛型超类?附泛型超类实现代码

如何将Spring实体传递给泛型超类RootQueryCreator?

我来给你梳理几种可行的实现方式,帮你把Spring实体传递给这个泛型超类:


1. 创建具体子类并通过构造函数传递实体

因为Spring无法直接实例化泛型类,你需要为每个实体创建对应的子类,明确指定泛型参数,然后在子类构造中传入实体实例:

首先定义你的Spring实体(比如User):

@Entity
public class User {
    // 实体字段、getter/setter 及 JPA 注解
}

然后创建继承自RootQueryCreator的子类,在构造函数中调用父类的带参构造传递实体:

@Repository
public class UserQueryCreator extends RootQueryCreator<User> {
    public UserQueryCreator() {
        super(new User()); // 传递User实体实例给父类
    }
}

这样Spring会自动扫描这个子类并创建Bean,同时父类的entity字段会被正确赋值,后续initRootQuery方法也能基于该实体构建查询。


2. 通过配置类手动创建Bean实例

如果你不想为每个实体都写子类,可以在Spring配置类中直接创建泛型超类的实例,指定具体实体类型并传递实体:

@Configuration
public class QueryCreatorConfig {
    @PersistenceContext
    private EntityManager em;

    @Bean
    public RootQueryCreator<User> userQueryCreator() {
        RootQueryCreator<User> creator = new RootQueryCreator<>(new User());
        // 因为父类的em是@PersistenceContext注入,Spring会自动为这个Bean注入EntityManager
        return creator;
    }

    // 其他实体的QueryCreator Bean同理
    @Bean
    public RootQueryCreator<Order> orderQueryCreator() {
        return new RootQueryCreator<>(new Order());
    }
}

3. 优化:通过反射获取实体类型(替代传递实体实例)

其实你的父类中持有T entity主要是为了获取实体类型,完全可以通过反射获取泛型的实际类型,避免手动传递实体实例。修改父类的初始化逻辑:

@Repository
public abstract class RootQueryCreator<T> { 
    @PersistenceContext 
    private EntityManager em; 
    private Class<T> entityClass; 
    CriteriaBuilder criteriaBuilder = null; 
    CriteriaQuery<T> criteriaQuery = null; 
    Root<T> rootTable = null; 

    @PostConstruct 
    public void initRootQuery() { 
        // 通过反射获取泛型实际类型
        Type type = getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        entityClass = (Class<T>) paramType.getActualTypeArguments()[0];
        
        criteriaBuilder = em.getCriteriaBuilder(); 
        criteriaQuery = criteriaBuilder.createQuery(entityClass);
        rootTable = criteriaQuery.from(entityClass);
    } 
}

然后子类只需继承并指定泛型参数即可,无需传递实体实例:

@Repository
public class UserQueryCreator extends RootQueryCreator<User> {
    // 空构造即可
}

这种方式更优雅,避免了手动new实体实例的冗余操作。


内容的提问来源于stack exchange,提问作者Markus Schnee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:30:12