java - 在 Java EE 和 CDI 中,根据数据库中存储的配置值选择要注入(inject)的实现是一个好习惯吗?

标签 java jpa dependency-injection cdi java-ee-7

我的任务是使用 JavaEE 7 用 java 重写数据库过程中存储的一些旧逻辑。该应用程序部署在 JBoss EAP 7 上。

这是一个关键功能,因此我们需要某种切换器,以便能够在生产中的某些服务的新旧实现之间快速切换。

不幸的是,即使出现严重问题,我们也无法立即交付和部署新版本。所以我们需要以数据库表的形式引入这样的切换器。

为了提供良好的可维护性,我想使用 CDI 来注入(inject)基于切换器的旧/新实现。

我认为最简单的方法是利用 CDI Producers。在生产者方法中发出数据库请求是一个好的解决方案吗?

我的例子:

@ApplicationScoped
public class NewServiceProducer {

    @Inject
    private ImplementationSwitcherDAO implementationSwitcherDAO;

    @Produces
    @RequestScoped
    public NewService produceNewService(){
        //a DB-Call is done here        
        boolean useOldVersion = implementationSwitcherDAO.isUseOldVersionForService("NewService");

        if(useOldVersion){
            return CDI.current().select(NewServiceOldImpl.class).get();
        }

        return CDI.current().select(NewServiceImpl.class).get();
    }
}

最佳答案

我无法真正评论“良好实践”问题,但您在这里有一个值得回答的问题。

要执行您想要的操作,您需要执行以下操作中的一项,但不能同时执行两项:

  1. 确保 NewServiceOldImpl.classNewServiceImpl.class 在其 bean types 集中NewService
  2. 完全否决 NewServiceOldImpl.classNewServiceImpl.class

否则,如果您尝试@Inject一个NewService,将会有两种可能性,并且,在其他条件相同的情况下,CDI 将会失败并出现某种 >AmbigouslyResolutionException

我会像这样实现你的解决方案:

// Let's assume that NewServiceImpl is a regular managed bean
@RequestScoped
@Typed({ NewServiceImpl.class, Object.class }) // ...or whatever, but not NewService.class
public class NewServiceImpl { /*...*/ }

// Let's assume that NewServiceOldImpl is a regular managed bean
@RequestScoped
@Typed({ NewServiceOldImpl.class, Object.class }) // ...or whatever, but not NewService.class
public class NewServiceOldImpl { /*...*/ }

// Then somewhere else:
@Produces
@RequestScoped
private static NewService produceNewService(final NewServiceOldImpl oldImpl,
                                            final NewServiceImpl newImpl) {
  if (implementationSwitcherDAO.isUseOldVersionForService("NewService")) {
    return oldImpl;
  }
  return newImpl;
}

关于java - 在 Java EE 和 CDI 中,根据数据库中存储的配置值选择要注入(inject)的实现是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60967430/

相关文章:

java - 使用 servlet、ajax、jquery 将图像发送到 mySQL

java - 关于在同一端口上运行多个应用程序

java - Hibernate 是否支持 Postgres 9.2 Json 数据类型?

java - 使用 JPA,是否可以将关系表作为 @Entity 映射到 java.util.Map?

c# - 使用 Unity 注入(inject)特定实现

java - 如何制作人脸检测中侧面的xml文件

java - 在 Junit 4 中构建测试套件

jpa - 获取由 : org. hibernate.AnnotationException 引起的错误:针对未映射的类使用 @OneToMany 或 @ManyToMany

c# - 服务定位器比依赖注入(inject)更容易使用?

java - Spring MVC,将 Hibernate 服务注入(inject) Spring bean 失败,不知道为什么