【问题标题】:Define bean using factory method in plain Java EE - WITHOUT Spring在纯 Java EE 中使用工厂方法定义 bean - 没有 Spring
【发布时间】:2015-08-01 10:46:59
【问题描述】:

我想创建一个可以由普通 Java EE 自动注入(自动装配)的 bean,不能使用 Spring

我的代码是这样的:

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

@ApplicationScoped
public class MyConnector {
    ....
    private Client client = ClientBuilder.newClient();
    ....
}

我想改用这样的依赖注入:

    @Inject
    private Client client;

在良好的旧 Spring 中,我将按照指南 http://docs.spring.io/spring/docs/3.1.0.M1/spring-framework-reference/html/beans.html#beans-factory-class-static-factory-method 定义 bean

<bean id="client"
    class="javax.ws.rs.client.ClientBuilder"
    factory-method="createInstance"/>

@Autowired 会注入正确的 bean。

问题:我可以在没有 Spring 的 普通 Java EE 中以某种方式实现相同的目标吗?我可以用类似的方式定义一个 bean - 如果可以,在哪里(在哪个配置文件中)?

【问题讨论】:

    标签: java jakarta-ee dependency-injection autowired inject


    【解决方案1】:

    您可以为此编写自己的 CDI 生产者

    @Dependent public ClientFactory{
       @Produces Client createClient() {
           return ClientBuilder.newClient(); 
       }
    }
    

    现在您可以使用 CDI 的 @Inject 在您的 Bean 中获取实例

    @ApplicationScoped public class MyConnector {    
        @Inject private Client client;
    }
    

    对于这些生产者,CDI 提供了一种易于使用的工厂模式实现。您几乎可以在任何地方注入所有内容,不仅是类,还包括接口、其他 JEE 资源甚至原始类型。注入点不必是类成员,但也可以是例如方法中的参数 ...

    每次注入都会为您提供不同的代理,因此您可以在必要时向您的 Bean 注入多个客户端。这些 Proxy 对象是否引用相同的实例取决于您对工厂方法的实现,但通常您不希望这样做。

    【讨论】:

    • 感谢您的解释! 1.请将您的ClientBuilder重命名为ClientFactory,否则会与已有的ClientBuilder发生冲突。 2. 为什么你的ClientBuilder类必须是@Dependent,而不仅仅是@ApplicationScoped左右?
    • @HonzaZidek 1. 我已经更新了代码。我只是没有意识到您正在使用 ws 客户端和 ClientBuilder。我的回答对您能够以这种方式注入的所有类型的您自己的类都有效。.. 2. 不一定,但如果没有必要,为什么要将自己限制在特定范围内?您也可以完全摆脱 @Dependent 注释(无需用不同的注释替换它),但我对此不是 100% 确定。应该也可以,但我还没有测试它。 @Dependent 是默认作用域
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多