JBoss Community Archive (Read Only)

Errai

A Gentle Introduction to CDI

This section is based on the previous guide sections

The project you created and setup in the previous two sections (ERRAI:Create your Project and ERRAI:Configuring your project for Eclipse) will be used as the basis for this section. So if you have not read them, do so now.

Errai CDI as its namesake implies is based on, and is in fact, a partial implementation of the CDI (Contexts and Dependency Injection) specification. Errai CDI covers most of the programming model but omits the CDI SPI, instead replacing it with it a custom set of APIs which are more appropriate for the client programming model of Errai.

These differences aside, using Errai CDI in conjunction with CDI on the server will provide you with a uniform programming model across the client and server code of your application.

This guide does not assume any past experience with CDI. However, you may wish to consider reading the the Weld Documentation in addition to this guide.

Your First Bean

A bean in CDI is merely a POJO (Plain Old Java Object), for the most part. In the context of CDI, any plain, default constructable class is a member of the dependent scope. Don't worry too much about what that means for now. Let's just go ahead and make one:

public class Foo {
  public String getName() {
    return "Mr. Foo";
  }
}

That was an easy, if uninteresting, exercise. But despite this class' worthy distinction as a dependent-scoped bean, it's actually quite a useless dependent scope beaned. Well, maybe not so much useless as it is unused.

Well, how would we use this bean? To answer that question we're going to need to introduce the concept of scopes in more detail.

Scopes

Scopes, put simply, are the context within which beans live. Some scopes are short-lived and some are long-lived. For instance, there are beans which you may only want to create during a request, and beans which you want to live for as long as the application is running.

It turns out that CDI includes a set of default scopes which represent these very things.

We'll start by taking a look at the application scope, which is lovingly represented by the annotation @ApplicationScoped. An application-scoped bean is a bean which will live for the entire duration of the application. In this sense, it is essentially like a singleton. And it's generally okay to think of it in that way.

So let's declare an application-scoped bean:

@ApplicationScoped
public class Bar {
  public String getName() {
    return "Mr. Bar";
  }
}

That was almost as easy as making the last bean. The difference between this bean and the last, is Bar will actually be instantiated by the container automatically, and Foo will not.

So what can we do with Foo? Well, let's go ahead and get familiar with dependency injection, shall we?

@ApplicationScoped
public class Bar {
  @Inject Foo foo; 

  public String getName() {
    return "Mr. Bar";
  }
}

We have added a field of the type Foo which we declared earlier, and we have annotated it with javax.inject.Inject. This tells the container to inject an instance of Foo into our bean. Since our Foo bean is of the dependent scope, the bean manager will actually create a new instance of Foo and pass it in.

This scope of the newly instantiated Foo is dependent on the scope that it was injected into. In this case, the application scope. On the other hand, if we were to turn around an inject Bar into Foo, the behaviour is quite different.

public class Foo {
  @Inject Bar bar; 

  public String getName() {
    return "Mr. Foo";
  }
}

Here, every time a new instance of Foo is created, the same instance of Bar will be injected. That is to say: this pseudo-code assertion is now always true:

assert fooInstance.bar.foo == fooInstance

Note: This identity check will not actually be true at runtime due to the need to proxy the class in this scenario. But it is true, that fooInstance and fooInstance.bar.foo both point to the same underlying bean instance.

In the case of an Errai application, there are a bunch of application scoped beans which come built-in for common services like _ErraiBus_. Thus, in an Errai application which uses the message bus, we can inject a handle to the MessageBus service into any of our beans. Let's go ahead and do that in our Bar class:

@ApplicationScoped
public class Bar {
  @Inject Foo foo; 
  @Inject MessageBus bus;

  public String getName() {
    return "Mr. Bar";
  }
}

If working with dependency injection is new to you, then this is where you'll start seeing some practical benefit. When you need a common service in your client code, you ask the container for it, by injecting it. This frees you of worrying about the proper APIs to use in order to get access to a service; we need to use the message bus in our Bar bean, and so we inject it.

Now that we're getting the gist of how dependency injection works, let's go back to the sample project we created with the Maven archetype in the last section of this guide.

In the App class that was created, there may be two peculiarities sticking out to you:

1. The bean's scope is @EntryPoint; and
2. we're injecting the type Event<HelloMessage> into our bean.

The @EntryPoint annotation is an annotation which provides a an analogue to the GWT EntryPoint concept within the context of CDI in Errai. Basically you want to think of @EntryPoint beans as the Errai CDI-equalivalent of main() methods. But as of Errai 2.2., that might actually be going a little far. In fact, you might be asking what is the real difference between @ApplicationScoped and @EntryPoint in practice. The short answer is: nothing.

When Errai IOC, the technology which powers Errai's client-side CDI, was first built, it lacked the concept of scopes. To create entry point objects into the application which would automatically run, this annotation was added. The reason it hasn't been deprecated is for two reasons: we still support plain old Errai IOC, and further, we intend to add more useful semantics to @EntryPoint in Errai 3.0.

The second item brings us to the next concept: CDI Events.

CDI Eventing

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-10 12:35:37 UTC, last content change 2013-10-15 19:40:53 UTC.