Vaadin应用程序中单例EJB注入失败

时间:2014-02-13 21:09:24

标签: ejb vaadin cdi

我正在玩Vaadin的Charts和CDI附加组件,我正在尝试将模拟数据源注入Chart类。数据源是一个单例bean,它已经在View中注入了一个将显示图表的引用,但我认为这应该不重要,因为单例是应用程序作用域。

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();

1 个答案:

答案 0 :(得分:0)

好的 - 看起来这个问题归咎于我的无知,因为我不理解允许EJB注入的上下文。

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

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

从错误中吸取教训。按照我正在制作它的速度,我将成为一个天才!