Java 可以在运行时动态实例化DAO类吗?

Java 可以在运行时动态实例化DAO类吗?,java,cdi,entitymanager,reflections,Java,Cdi,Entitymanager,Reflections,所以我四处找了一下,但仍然找不到任何能帮助我的东西。这是我的代码: public ExtendedBaseDAO getCorrespondingDAO(String tableName) throws DAOException { log.info("BaseService.getCorrespondingDAO(...): Getting DAO correspondant to table with name " + tableName

所以我四处找了一下,但仍然找不到任何能帮助我的东西。这是我的代码:

public ExtendedBaseDAO getCorrespondingDAO(String tableName) throws DAOException {
        log.info("BaseService.getCorrespondingDAO(...): Getting DAO correspondant to table with name " + tableName
                + "...");
        try {
            Optional<EntityType<?>> entityFound = entityManager.getMetamodel().getEntities().stream()
                    .filter(entity -> ((Table) entity.getJavaType().getAnnotation(Table.class)).name().equalsIgnoreCase(tableName)).findFirst();
            log.info("Found entity with name " + entityFound.get().getJavaType().getSimpleName() + " mapped to " + tableName);
            Reflections reflections = new Reflections("eu.unicredit.fit.fit_core.dao");
            Optional<Class<? extends ExtendedBaseDAO>> daoClassFound = reflections.getSubTypesOf(ExtendedBaseDAO.class)
                    .stream().filter(daoClass -> daoClass.getSimpleName().replaceAll("DAO", "")
                            .equals(entityFound.get().getJavaType().getSimpleName()))
                    .findFirst();
            
            log.info("The correspondant DAO found is " + daoClassFound.get().getSimpleName() + ". Instantiating it...");
            return daoClassFound.get().getConstructor().newInstance();
        } catch (Exception e) {
            throw new DAOException("It was not possible to find the DAO associated with the table " + tableName
                    + "! Error: " + e.getLocalizedMessage());
        }
    }
public ExtendedBaseDAO getCorrespondingDAO(String tableName)引发异常{
log.info(“BaseService.getCorrespondingDAO(…):将DAO对应到名为“+tableName”的表
+ "...");
试一试{

可选因为您控制着DAO类,所以我认为将字符串动态转换为bean的最简单解决方案是使用带有绑定成员的CDI限定符(请参见CDI 2.0规范第5.2.6节)

因此,您已经:

公共抽象类ExtendedBaseDAO扩展BaseDao{{
...
}
@适用范围
公共类WizardFieldConfigDAO扩展了ExtendedBaseDAO{
...
}
@适用范围
公共类OtherDAO扩展了ExtendedBaseDAO{
...
}
使用绑定成员定义限定符批注:

@限定符
@保留(运行时)
@目标({方法,字段,参数,类型})
公共@interface MyDao{
字符串tableName();
}
将其添加到您的bean中:

@MyDao(tableName=“其他”)
@适用范围
公共类WizardFieldConfigDAO扩展了ExtendedBaseDAO{…}
@MyDao(tableName=“其他”)
@适用范围
公共类OtherDAO扩展了ExtendedBaseDAO{…}
创建实用工具注释文字:

import javax.enterprise.util.AnnotationLiteral;
公共类MyDaoQualifier扩展AnnotationLiteral实现MyDao{
私有字符串表名;
公共MyDaoQualifier(字符串表名){
this.tableName=tableName;
}
@凌驾
公共字符串tableName(){
返回表名;
}
}
像这样理解:

@Inject@Any

私有实例呃,注入
ApplicationContext
并从那里获取bean?当然你不能对它使用反射。Spring怎么知道如何正确初始化它。你控制DAO类吗?你能在它们上添加CDI限定符注释吗?如果能,你可以使用CDI的
实例
动态检索它们ant要(或必须)使用反射,并且您知道DAO只依赖于
EntityManager
,您可以添加构造函数(或setter)并在反射构造上调用它。如果您可以添加一个方法
ExtendedBaseDAO.setEntityManager
,它将极大地简化事情。@NikosParaskevopoulos是的,我控制着DAO类。我如何动态检索它们?您能回答堆栈问题吗?这样,如果它确实有效,我会将其标记为已接受。还有seco第二个建议,我想了一下,但它在结构上不是错了吗?我是说ofc我可以在包含getCorrespondingDAO的类中注入EntityManager,然后将该实体管理器传递给setter。这是个好主意吗?@Kayaman很遗憾,我没有使用spring。我理解这种混乱,因此添加了一个编辑非常感谢。刚刚测试过它,它非常有效。CDI实际上有一些很好的隐藏功能,我想,在网上找不到。
public class WizardFieldConfigService extends BaseService {

    @Inject
    private WizardFieldConfigDAO wizardFieldConfigDAO;

    /**
     * Retrieves the field data from the specific table requested for. To specify
     * the table use the fieldDataRequest.
     * 
     * @param fieldDataRequest The DTO to be used as input
     * @return a {@link FieldDataResponseDTO} object with a map containing the
     *         requested values
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public FieldDataResponseDTO getFieldData(FieldDataRequestDTO fieldDataRequest) {
        log.info("WizardFieldConfigService.getFieldData(...): Retrieving field data for field with id "
                + fieldDataRequest.getFieldID() + "...");
        
        WizardFieldConfig fieldBaseData = wizardFieldConfigDAO.findByID((long)fieldDataRequest.getFieldID());
        log.info("Found field data: " + fieldBaseData.toString());
        
        List<BaseEntity> response = getCorrespondingDAO(fieldBaseData.getDomainName())
                .findWithConditions(fieldDataRequest.getConditions());
        
        return new FieldDataResponseDTO().setPlaceHolder(fieldBaseData.getPlaceholder())
                .setLabel(fieldBaseData.getFieldName()).setRegex(fieldBaseData.getRegex())
                .setValueList((Map<? extends Serializable, String>) response.stream()
                        .collect(Collectors.toMap(BaseEntity::getId, BaseEntity::getDescription)));
    }

}
@PersistenceContext(unitName = "fit-core-em")
private EntityManager em;

protected ExtendedBaseDAO(Class<T> type) {
    super(type);
}

public List<T> findWithConditions(List<ConditionDTO> conditions) {
    //...
}


@Override
protected EntityManager getEntityManager() {
    return this.em;
}