标签: cdi

如何强制使用CDI生产者方法?

我的部分问题是使用适当的词汇表,所以我提前道歉可能是一个简单的术语问题.

假设我有一个Person接口,以及一个PersonBean实现该接口的类.

假设我在某处(注释@Produces)有一个返回a 的生成器方法Person.在内部它返回一个新的PersonBean,但这既不在这里也不在那里.

最后,假设我有另一个CDI bean,其注入点定义如下:

@Inject
private Person person;
Run Code Online (Sandbox Code Playgroud)

假设我已经将我的所有beans.xml文件都放在适当的位置,并且已经引导了Weld或其他符合CDI-1.0标准的环境,因为这一切都将导致模糊的定义错误.这是有道理的:Weld将找到我PersonBean作为注入的候选者(它可以只调用构造函数)并且将找到我的producer方法的输出作为注入的候选者.

我想要做的是以某种方式强制Person在此应用程序中生成实例始终路由生成器方法.

我知道我可以在某处创建一些限定符,并使生成器方法生成Person由该限定符限定的实例.如果我这样做,并改变我的注射点以包括限定符,那么显然这些合格的注射剂只有一个来源(即我的生产者方法),所以,问题解决了.

但是假设我不想发明一些虚假的限定词.(我不是说这是事实;只是想更深入地了解这些问题.)我有什么选择?我有吗?我想我可以把@Typed(Object.class)PersonBean做出这等,这是不看作是一个Person由CDI ....

欢迎任何想法,包括指向文档,或更好地理解这一点.谢谢.

jsr299 cdi

5
推荐指数
1
解决办法
2058
查看次数

使用JAX-RS 2.0和CDI/Weld代替Guice的优势?

JAX-RS 2.0的一个目标是整合CDI并用旧的替代@Context普通@Inject注射.但是如果我看一下JSR 339,就没有提到.那么CDI整合究竟是什么呢?将JAX-RS与CDI而不是Google Guice一起使用是否有任何优势?

java jax-rs guice cdi weld

5
推荐指数
1
解决办法
653
查看次数

CDI @Producer方法可以采用自定义参数吗?

我想我理解CDI是如何工作的,为了深入研究它,我想尝试用一些真实世界的例子.我被困在一件事情,我需要你的帮助才能让我理解.在这方面,我非常感谢你的帮助.

我有自己的工作流框架使用Java反射API和XML配置开发,其中基于特定类型的"source"和"eventName",我加载适当的Module类并在其上调用"process"方法.一切都在我们的项目中运作良好.

我对CDI功能很兴奋,并希望尝试使用工作流框架,我计划注入Module类,而不是使用Reflection等加载它们...

只是为了给你一个想法,我会尽量在这里保持简单.

"Message.java"是一种带有"Source"和"eventName"的Transfer Object,因此我们可以适当地加载模块.

public class Message{
private String source;
private String eventName;
}
Run Code Online (Sandbox Code Playgroud)

模块配置如下

<modules>
<module>
    <source>A</source>
    <eventName>validate</eventName>
    <moduleClass>ValidatorModule</moduleClass>
</module>
<module>
    <source>B</source>
    <eventName>generate</eventName>
    <moduleClass>GeneratorModule</moduleClass>
</module>
</modules>
Run Code Online (Sandbox Code Playgroud)

ModuleLoader.java

public class ModuleLoader {
public void loadAndProcess(Message message){
    String source=message.getSource();
    String eventName=message.getEventName();

    //Load Module based on above values.

}
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想通过CDI实现相同的注入模块(在ModuleLoader类中),我可以使用@Produce方法编写Factory类,这可以做到这一点.但我的问题是,

a)如何将Message Object传递给@Produce方法,以便根据eventName和source进行查找?

你能给我一些建议吗?

提前致谢.

cdi

5
推荐指数
1
解决办法
6706
查看次数

无法在JAX-RS服务中注入@ApplicationScoped bean

我已经创建了JAX-RS服务,我想在其中注入一个应用程序范围的bean.问题是没有注入豆子.这是怎么造成的,我该如何解决?

JAX-RS服务:

@Path("room")
public class RoomService {

    @Inject
    GameController gc;

    public RoomService() {}

    @Path("create")
    @GET
    @Produces("application/json")
    public String create() {
        Room r = new Room();
        gc.addRoom(r); // gc is null
        return r.toJson();
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序作用域bean

import java.util.ArrayList;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import pepuch.multuplayergameserver.entity.Game;
import pepuch.multuplayergameserver.entity.Room;

@Named
@ApplicationScoped
public class GameController {

    private Game game;

    public GameController() {
        this.game = new Game(new ArrayList<Room>());
    }

    public boolean addRoom(Room room) {
        if (!game.getRooms().contains(room)) {
            return game.getRooms().add(room);
        }

        return false;
    }

}
Run Code Online (Sandbox Code Playgroud)

jax-rs java-ee cdi

5
推荐指数
1
解决办法
6762
查看次数

commandButton单击p:dataTable导致在应用程序调用后重新生成@ViewScoped bean

风景:

<h:form ...
  <p:dataTable value="#{myBean.list}" var="data" ...
     <p:column ...
        <h:commandButton action="#{controller.method(data.id)}" />
     </p:column>
  </p:dataTable>
</h:form>
Run Code Online (Sandbox Code Playgroud)

控制器:

@ApplicationScoped
public class Controller {
   public String method(final Long dataId) {
        /* Do business */
        return URL_WITH_REDIRECT;
   }
}
Run Code Online (Sandbox Code Playgroud)

制片人

(使用此处@ViewScoped描述的CDI注释)

@ApplicationScoped
public class Producer {
   @Named @ViewScoped @Producer
   public MyBean getMyBean() {
        final MyBean bean = new MyBean();
        bean.list = new ArrayList<Data>(); // where Data has a Long id field
        /* Do business and populate list */
        return bean;
   } …
Run Code Online (Sandbox Code Playgroud)

java jsf glassfish cdi view-scope

5
推荐指数
1
解决办法
1771
查看次数

迁移到Java EE 7后,CDI无法正常工作

我最近将一个简单的Java EE 6项目迁移到了Java EE 7.详细地说,这意味着我只是将依赖关系更改javax:javaee-api:6.0javax:javaee-api:7.0并将其部署到Glassfish 4而不是Glassfish 3.

之后应用程序不再起作用,因为CDI无法注入带注释的依赖项.

glassfish java-ee cdi glassfish-4 java-ee-7

5
推荐指数
1
解决办法
4439
查看次数

为什么CDI bean类的构造函数不止一次被调用

我用@ApplicationScoped注释了一个类.使用@Inject,我将这个类的实例注入到几个@RequestScopded JAX-RS服务中:

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
}

@RequestScoped
public class MyRS {
  @Inject MySingleton mySingleton;
  public void someMethod() {
    // do something with mySingleton
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上这很好用.Howeger,至少当我在WebSphere 8.5中运行它时,MySingleton的构造函数被调用两次,导致输出像

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.
Run Code Online (Sandbox Code Playgroud)

我打算在构造函数中做一些昂贵的初始化,显然会执行两次.

我相信其中一个构造函数调用是为实际的"worker"实例生成某种代理.但是如何避免我的初始化代码执行两次?在MySingleton的所有方法中进行延迟初始化的"解决方案"并不是很有吸引力.

constructor java-ee cdi managed-bean

5
推荐指数
1
解决办法
2168
查看次数

在构造函数或后期方法中初始化CDI注入的组件?

我在Vaadin上下文中使用CDI,但这对我的问题无关紧要:在构造函数中注入对象或者直接作为成员变量注入更好吗?特别是如果必须进一步配置这些对象以使组件工作.

以下显示了两种不同的CDI可能性:

@UIScoped
public class MyMenuBar extends CustomComponent {
    @Inject @New private Label label;
    @Inject @New private MenuBar menuBar;

    @PostConstruct
    private void init() {
        //set label text, define menu entries
        setCompositionRoot(menuBar);
    }
}

@UIScoped
public class MyMenuBar extends CustomComponent {
    private Label label;
    private MenuBar menuBar;

    @Inject
    public MyMenuBar(@New Label label, @New MenuBar menuBar) {
        //set label text, define menu entries
        setCompositionRoot(menuBar);
    }
}
Run Code Online (Sandbox Code Playgroud)

有最好的做法吗?为什么一个人更喜欢一个选项?或者这仅仅是个人选择的问题?

java java-ee vaadin cdi

5
推荐指数
2
解决办法
2851
查看次数

什么时候注入bean实际初始化?

我的代码库中有以下场景:

//this bean, which will be injected,
//is not annotated
public class HelperUtil {
   //only default constructor with no args

   public void doThis(String _in) {
      //...
   }

   public void doThat() {
      //...
   }
}
Run Code Online (Sandbox Code Playgroud)

在下面的课程中我们进行注射:

@Named
@Stateless
public class BusinessManager {

    @PersistenceContext(unitName = "default")
    private EntityManager em;

    @Inject
    private HelperUtil helperUtil ;

    //...
}
Run Code Online (Sandbox Code Playgroud)

Q1: 何时HelperUtil通过调用默认构造函数实际初始化实例?当注入它的第一个客户端(例如BusinessManager)在应用服务器(在我的情况下JBoss)启动时被实例化(并且由于它被注释为将由容器初始化),它是否已完成@Stateless

Q2: 在上面的展览中,只要没有客户端以外的客户端通过直接调用构造函数而不是通过?获取实例来请求实例,它将HelperUtil保持不变?singletonDI

问题3: 使用DI的优势是什么?@Inject在这种情况下直接调用构造函数(HelperUtil helper = new HelperUtil();)?

java jboss dependency-injection cdi

5
推荐指数
1
解决办法
4121
查看次数

CDI会话范围bean未被破坏导致内存泄漏

我对会话作用域CDI bean的生命周期有疑问.
据我所知,会话范围内的CDI bean是在会话开始时由容器构造的,并在会话结束时销毁.在销毁bean之前,调用@PreDestroy方法,如https://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html所述.它还说要在这种方法中释放资源.

在我构建的JSF应用程序中,我遇到内存泄漏,因为bean似乎没有被销毁,因此不会调用@PreDestroy方法来释放垃圾收集器的一些引用.所以我构建了一个简单的应用程序来测试行为.我的经验是会话bean在会话结束时不会被破坏,而且当需要内存空间时它甚至不会被破坏.我不敢相信我是第一个遇到这种情况的人,但我没有找到任何有关此行为的信息.

所以我的问题是:在上下文过期之后,不应该销毁CDI bean - 因此调用@PreDestroy方法吗?如果不是,在需要空间时,它至少应该被破坏吗?

我的测试应用:

我不允许发布图片,但大纲是eclipse生成的非常基本的jsf webapp.我也有beans.xml文件.

Test.java:

package com.test;

import java.io.Serializable;
import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@SessionScoped
@Named
public class Test implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String test;
    private ArrayList<ComplexType> cps;
    private ArrayList<ComplexType> cps_2;

    @PostConstruct
    public void init() {
        System.out.println("test postconstruct..");
        test = "Cdi Test";
    }

    @PreDestroy
    public void cleanUp() {
        cps …
Run Code Online (Sandbox Code Playgroud)

jsf session-scope destroy cdi weld

5
推荐指数
2
解决办法
2889
查看次数