【问题标题】:Failure of singleton EJB injection in Vaadin applicationVaadin 应用程序中的单例 EJB 注入失败
【发布时间】:2014-02-13 21:09:23
【问题描述】:

我目前正在为 Vaadin 使用 Charts 和 CDI 插件,并尝试将模拟数据源注入 Chart 类。数据源是一个单例 bean,它已经将一个引用注入到将显示图表的视图中,但我的印象是这应该无关紧要,因为单例是应用程序范围的。

EJB 已正确注入到视图中,但在实例化图表类时,数据源的注入失败并返回空引用。到目前为止,我一直在使用无接口工具,但即使我确实为数据源使用了接口,这也没有任何区别。我猜要么存在范围界定问题,要么我从根本上滥用/误解了 CDI。另一种可能性是我遇到了对 Vaadin CDI 插件的限制,因为这种方法在 JSF2.2 中没有问题。

如果有人有任何想法或建议,我将非常感激,因为这非常令人沮丧。当然这是一个快速而肮脏的实现,但它是一个原型;重构以分离关注点(数据提供与构建 UI 组件)可能会很好地解决问题,但我想先了解这里发生了什么。

EJB:

@Startup
@Singleton
public class MockDataProvider implements Serializable {
    private static final long serialVersionUID = -4789949304830373309L;
    private Random rand = new Random();
    private Collection<Person> people = new ArrayList<Person>();
    private Collection<Address> addresses = new ArrayList<Address>();
    private Collection<Evnt> evnts = new ArrayList<Evnt>();
    private Collection<TicketType> tickets = new ArrayList<TicketType>();


    /**
     * Initialize the data for the application
     */
    public MockDataProvider() {
    }

    @PostConstruct
    private void init() {
        loadAddressData();
        loadTicketData();
        loadEventData();
        loadPersonData();
    }

查看实现(此处注入成功):

@CDIView(DashboardView.VIEW_ID)
public class DashboardView extends AbstractMVPView implements IDashboardView {
    public final static String VIEW_ID = "dashboard";

    @Inject
    @CDILogger
    private Logger logger;

    @EJB
    MockDataProvider dataProvider;

    @Inject
    EventsPerMonthChart eventsPerMonthChart;

    private Table eventsTable;

    private Table peopleTable;

    public DashboardView() {
    }

Chart 类(由 DashboardView 实现 - EJB 注入失败,因此 dataProvider.getEvntCollection 会抛出空指针异常。

@Dependent
public class EventsPerMonthChart extends Chart {

    @EJB
    MockDataProvider dataProvider;

    public EventsPerMonthChart() {
        super(ChartType.PIE);

        setCaption("Events per month");
        getConfiguration().setTitle("");
        getConfiguration().getChart().setType(ChartType.PIE);
        setWidth("100%");
        setHeight("90%");

        DataSeries series = new DataSeries();

        ArrayList<Evnt> events = (ArrayList) dataProvider.getEvntCollection();

【问题讨论】:

  • 注入是静默失败还是有异常?你的运行时间是什么?
  • 注入失败。开发环境如下:Java EE 7、Vaadin 7.1.11,带有最新的 CDI 和 Charts 插件。 beans.xml 文件就位,通过生产者方法注入布局没有问题。

标签: ejb vaadin cdi


【解决方案1】:

好的 - 问题似乎归结为我的无知,因为我不了解允许 EJB 注入的上下文。

EJB (MockDataProvider) 由容器实例化并注入到 DashboardView 类中,因为它使用 @CDIView 注释,所以也由容器管理。因此,一切正常。但是,Chart 对象不是容器管理的(尽管我错误地添加了@Dependent 以尝试让容器“注意到”它)- 不允许注入 POJO,但似乎默默地失败了,这只会增加我的困惑。

诚然,代码结构非常令人震惊(紧密耦合、高度依赖且没有关注点分离),而这种粗制滥造的原型设计方法是造成问题的原因。直接向 Charts 对象传递数据或通过构造函数调用对 EJB 的引用都可以正常工作。

干得好,你从错误中吸取教训。以我制作它们的速度,我将成为一个天才!

【讨论】:

  • 当然,在正常情况下我不想注入 UI 组件(低级布局可能例外)。在这种情况下使用 CDI 似乎与标准 POJO 相比没有任何优势。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多