gpt4 book ai didi

Java EE 单例反射注入(inject)

转载 作者:行者123 更新时间:2023-11-30 03:16:23 24 4
gpt4 key购买 nike

Java EE 让我(又一个)头疼(Wildfly 8+):

首先,想象一些 Singleton POJO,其中使用的实例由某个属性设置:

Java SE 单例

public class Singleton
{
private Singleton instance
public Singleton getInstance()
{
if (instance == null)
{
try
{
String className = System.getProperty("singletonClass");
instance = Class.forName(className).getInstance();
}
catch(Exception e)
{
...
}
}
return instance;
}
}

您可能会认为这种方法是糟糕的设计。但这就是我们的单例实例的“配置”方式。

现在我在 Java EE 世界中遇到了这种方法。我让它工作了,但它只是臃肿丑陋的注释 hell 代码 - 除此之外,我不太熟悉 Java EE,可能有更简单的方法:

ProjectManager(应该是抽象的)

@Singleton
@LocalBean
public class ProjectManager
{
...
}

项目经理实现

@Singleton
@LocalBean
public class DefaultProjectManager extends ProjectManager
{
}

生产者注释

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD
})
public @interface DynamicProjectManager
{

}

制作人

@ApplicationScoped
public class ProjectManagerProducer implements Serializable
{
@Inject
@Any
private Instance<ProjectManager> projectManagers;

@Produces
@DynamicProjectManager
private ProjectManager createProjectManager()
{
String clazz = System.getProperty("projectManagerType","DefaultProjectManager");
try
{
return projectManagers.select((Class<ProjectManager>) Class.forName(clazz)).get();
}
catch(Exception e)
{
return projectManagers.select(DefaultProjectManager.class).get();
}
}
}

用法在另一个Bean中:

@Inject
@DynamicProjectManager
private ProjectManager projectManager;

这有效!但我看到很多事情让我晚上睡不好觉。目前我没有使用其他框架(Spring 或类似的)。这是我的问题:

  1. Java EE 中是否有更简单的方法来支持单例(或其他 EJB),其中该单例的运行时类在编译时未知?
  2. 如果不是:是否可以仅注入(inject)单例实例而不使用额外的 @DynamicProjectManager 注解?
  3. 是否可以使 ProjectManager 变得抽象?

最佳答案

保持简单,除非绝对需要,否则不要将 EJB 与 CDI 混合使用。应执行以下操作:

public interface ProjectManager {
// add some method signatures
}


@ApplicationScoped
public class DefaultProjectManager implements ProjectManager {
// add implementations
}

public class ProjectManagerClient {

@Inject
private ProjectManager projectManager;

// work with injected bean
}

如果有多个ProjectManager周围的实现,您可以使用 @Alternative或者,如果您确实需要在运行时动态选择实现,则使用 Instance<ProjectManager>select()对于给定的限定符。

按类名选择是一种不好的做法,违反了松散耦合。最好在每个实现中使用不同的限定符,或者如果您更喜欢共享限定符,则添加 @NonBinding限定符的参数,因此您可以通过该参数的值进行选择。

关于Java EE 单例反射注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32483095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com