根据条件注入@EJB bean

发布于 2024-12-12 04:15:30 字数 297 浏览 0 评论 0原文

一个新手问题:无论如何,我是否可以根据我在属性文件中设置的条件注入不同的bean。这就是我想要实现的目标:

我在属性文件中设置了一些值。如果这是真的,那么我想

  public class MyClass{
    @EJB
    private MyBean bean;
  }

如果它是假的,那么

public class MyClass{
  @EJB
  private MyBean2 bean2;
 }

这可行吗?

A newbie question: is there anyway that I can inject different beans based on a condition that I set in a properties file. Here's what I want to achieve:

I set some value in properties file. If it's true, then I want to

  public class MyClass{
    @EJB
    private MyBean bean;
  }

if it's false, then

public class MyClass{
  @EJB
  private MyBean2 bean2;
 }

Is this doable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

子栖 2024-12-19 04:15:30

正如 Gonzalo 所说,如果您想将 bean 声明为类字段并使用它的不同实现,您首先需要指定 bean 的公共接口。

此外,我认为您可以使用 CDI 的 @Produces 方法更优雅地实现它;即在这两行之间:

@Singleton
@Startup
public class Configuration {

    private boolean someCondition;

    @PostConstruct
    private void init() {
        someCondition = ... // get a value from DB, JMS, XML, etc.
    } 

    @EJB(lookup="java:comp/env/myParticularBean")
    MyBean myBean1;

    @EJB(beanName="anotherTypeOfBeanInjectedByName")
    MyBean myBean2;

    @Produces
    public MyBean produceMyBean() {
        if (someCondition)
            return myBean1;
        } else {
            return myBean2;
        }
    }
}

然后在您的代码中您可以使用:

@Inject
MyBean myBean;

将根据您的条件为您注入适当的bean。

如果您不需要类级别的字段,您可以使用旧方法并在 JNDI 中定位 EJB - 通过这种方式,您可以控制应定位和使用的类型和 bean。

编辑:我添加了 @EJB 带注释的 bean,以显示“myBean1”和“myBean2”实例可能来自何处。

此示例表明您可以在一个地方定义对不同 EJB 实现和其他组件的所有依赖项。在示例中,这可以实现为带有 @EJB 字段、@PersistenceContext 字段等的单例 EJB。

您可以将 return myBean1 更改为类似 return context.lookup("JNDI_NAMESPACE_COORDINATES"),其中 contextInitialContext 的实例。

希望这能让它更清楚。

As Gonzalo said, you would firstly need to specify the common interface of the bean if you want to declare it as a class field and use different implementations of it.

Moreover, I think you could achieve it more elegant using the CDI's @Produces method; i.e. somewhat between these lines:

@Singleton
@Startup
public class Configuration {

    private boolean someCondition;

    @PostConstruct
    private void init() {
        someCondition = ... // get a value from DB, JMS, XML, etc.
    } 

    @EJB(lookup="java:comp/env/myParticularBean")
    MyBean myBean1;

    @EJB(beanName="anotherTypeOfBeanInjectedByName")
    MyBean myBean2;

    @Produces
    public MyBean produceMyBean() {
        if (someCondition)
            return myBean1;
        } else {
            return myBean2;
        }
    }
}

Then in your code you can just use:

@Inject
MyBean myBean;

An appropriate bean based on your condition will be injected for you.

If you don't need a field on class level you could use the old-way and locate the EJB in JNDI - in this way you have the control over what type and what bean should be located and used.

EDIT: I've added the @EJB annotated beans to show where the 'myBean1' and 'myBean2' instances might come from.

This example shows that you can have one, single place where you define all your dependencies on different EJB implementations and other components. In an example, this could be realised as a singleton EJB with @EJB fields, @PersistenceContext fields, etc.

Instead of doing it in the presented way, you can change return myBean1 to something like return context.lookup("JNDI_NAMESPACE_COORDINATES") where context is an instance of InitialContext.

Hope this makes it more clear.

于我来说 2024-12-19 04:15:30

我不认为你可以修改正在注入的 bean 的类型。我想说这是 Java 的限制,因为它是一种强类型语言 :)

但是,您可能会遇到多个 bean 实现相同接口的情况,并且您想要注入该接口的特定实现,如下所示:

@Local
public interface MyBean {
}

@Stateless
public class MyBeanImpl1 implements MyBean {
}

@Stateless
public class MyBeanImpl2 implements MyBean {
}

那么您可以这样做:

public MyClass {

@EJB(beanName="MyBeanImpl1")
MyBean myBean;

}

public MyClass {

@EJB(beanName="MyBeanImpl2")
MyBean myBean;

}

取决于您要注入的实现。

I don't think you can modify the type of the bean being injected. I would say this is a Java restriction as it is a strongly typed language :)

You can however have the scenario where multiple beans implement the same interface, and you want to inject a specific implementation of that interface, as follows:

@Local
public interface MyBean {
}

@Stateless
public class MyBeanImpl1 implements MyBean {
}

@Stateless
public class MyBeanImpl2 implements MyBean {
}

Then you could do:

public MyClass {

@EJB(beanName="MyBeanImpl1")
MyBean myBean;

}

or

public MyClass {

@EJB(beanName="MyBeanImpl2")
MyBean myBean;

}

Depending on the implementation you want to inject.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文