CDI Production

Dependency injection involves making things. Here’s a condensed version of how things are made in CDI. You may also be interested in my larger CDI tutorial.

This is a living document that I intend to update frequently. I may break it up into separate posts later.

We’re going to start from the bottom and inside, and work our way up and out. That means we’ll look at the low-level, internal machinery of CDI first, which most users rarely see. Then we will work up and out to annotated classes, from which the low-level constructs are derived, and which are what users create and manipulate.

Finally, terms in CDI can refer to each other, so it is definitely a challenge to present things in order. There will be times where I will ask you to take things on faith, and then will circle back to address them in more detail once the terms I need to talk about them are more firmly in place.

OK, off we go.

Contextuals

At the bottom of CDI you have Contextuals. Contextuals are stateless factories that create and destroy contextual instances. Think of a contextual instance, for now, as a regular Java object, although they can be more complicated than that.

One kind of Contextual is a Bean. A Bean is a Contextual paired with some descriptive and lifecycle-related attributes. We’ll assume that Beans are the only kind of Contextual in the world, so we’ll just talk about them instead.

Beans and Contextual Instances

The lifecycle of any contextual instances that a Bean creates is not under its control. It is instead reified by a Context that the Bean is indirectly affiliated with. A Context doesn’t create or destroy contextual instances, but it controls when they are created by Beans, stores them, and controls when they are destroyed by Beans.

When a Context needs a new instance—because, for example, it has been asked for one and doesn’t have one already stored—it always asks an affiliated, appropriate Bean to create one. This is why an instance created by a Bean and stored by a Context is therefore called a contextual instance. We will discuss why a Context might be asked for a contextual instance, and by whom, soon.

Even though we can’t really fully talk about them, there are some other characteristics of contextual instances that are worth mentioning up front, just to locate them in architectural space. They’re worth mentioning now because it is a Bean‘s create method that is ultimately responsible for them, not some other piece of CDI machinery. Don’t worry if you don’t understand these characteristics yet.

First, a contextual instance may be intercepted or decorated. Because of this, it may be a proxy object—proxying is a common strategy for implementing interception and decoration—or it may not. A Bean does not have to implement decoration or interception at all, but if they are to be implemented, they must be implemented, ultimately, by a Bean‘s create method, in whatever way it chooses. A Bean does not necessarily have to use proxying to implement these features. Don’t worry that we haven’t discussed interception, decoration or what it means for something to be a proxy object yet.

Second, under no circumstances will a contextual instance be a client proxy, a very specific CDI term that we will also cover later (that is sadly unrelated to the possible proxying discussed above). Beans never create client proxies. This will be relevant when we discuss dependency injection in more detail. For now, it is just an interesting fact using a term that has yet to be defined.

Third, a contextual instance is often an instance of a type that depends on other types. A Unicycle interface might depend on a Wheel class, for example: when a new Unicycle implementation of some kind is created (by a Bean), it may need to be supplied with a Wheel object. Acquiring and supplying these objects is, loosely speaking, dependency injection. We can’t fully talk about dependency injection yet, but for now just know that it is a Bean‘s create method’s job to perform it.

So much for Beans and the basics of who calls them and what they do.

Contexts

Rising up and out a level, low-level machinery within CDI can ask a Context for a contextual instance of something. It supplies a Context with a relevant Bean, and asks for an appropriate contextual instance that the Context manages on behalf of that Bean. The Context, in turn, may discover that it does not have an appropriate contextual instance yet, and so might turn around and ask the supplied Bean to create one. A Context never creates contextual instances itself.

A Context can be active or not with respect to a given Thread. There can be only one Context active for a Thread at a time and its activeness can change at any point for any reason.

Scopes

A Context is the partial or full implementation of a notional lifecycle represented by the concept of a scope. This means a Context stores a contextual instance created by a Bean for some period of time, for a given Thread. Or, perhaps it never stores anything but just arranges for contextual instances to be created every time it is asked for them. That is legal too, and in fact CDI depends on the existence of such a Context.

If a Context stores contextual instances, it typically (but, I suppose, not necessarily) does so by affiliating them in storage with the Bean that created them. This means that a Bean is both a mechanism for creating a contextual instance, and, often, a key to identify that contextual instance later.

As noted above, a Context implements part, or all, of a scope. A scope is a concept representing a notional lifecycle and is associated with one or more Contexts. Sometimes people talk about scopes and Contexts as if they are the same thing. They are not, since a scope may be implemented by one or more Contexts. Finally, a scope is notionally identified by its scope type, which is another notion that exists only to identify its scope. A scope may be identified by only one scope type and a scope type identifies only one scope.

A scope type is reified by a Java annotation type that itself must be annotated with either jakarta.inject.Scope or jakarta.enterprise.context.NormalScope. A scope is said to be a normal scope if its reifying annotation type is annotated with jakarta.enterprise.context.NormalScope, and a pseudo scope otherwise. (There are ways in CDI to programmatically register other kinds of arbitrary annotation types as scopes, but for now we’ll ignore those.) We will talk about scopes—particularly normal scopes—more fully in a little bit.

A Context has a method that can retrieve its associated scope type.

Linking Scopes, Contexts, Beans and Contextual Instances

Low-level machinery within CDI often finds itself armed with just a Bean and the need to get a contextual instance that a given Bean can create. To do this, it does not ask the Bean to create such an instance directly. If it did, it would bypass the useful lifecycle management machinery that Contexts implement.

Instead, it asks the Bean for its scope type—something every Bean has as part of its descriptive and lifecycle-related attributes—and then asks other low-level CDI machinery for all the Contexts that also have that scope annotation type and thus collectively implement the corresponding scope (usually there’s just one). From the resulting set of Contexts, it gets the one that is active for the current Thread. Then it passes the Bean to the Context and asks for a corresponding contextual instance. The contextual instance that is returned may have been a cached one or a new one; the caller does not know.

So much for the basics of Contexts and how they interact with Beans.

Normal and Pseudo Scopes

Rising up and out another level, recall that a scope may be a normal scope or a pseudo scope. A normal scope is, loosely speaking, one whose contract guarantees the user that any objects she sees whose types logically belong to that scope will be suitable no matter where they are used.

For example, consider a normal scope representing a request-oriented lifecycle, and a caller who takes delivery of an object whose type logically belongs to that request scope. Wherever in her system that object shows up, regardless of what she does with it, it should be the right object, i.e. the one for the current request, or should be invalid in some way if there is no current request, and so on. So she can’t just take delivery of an ordinary contextual instance, because an object can’t replace itself with another in some magic way.

To help with this, if a Context indicates that it implements a normal scope (remember, a Context can supply its scope annotation type, as can the Beans that make the contextual instances it manages), then a CDI implementation must do some prescribed things to ensure the normal scope contract is honored.

First, from the user’s perspective, if she receives a Unicycle object from as-yet-unspecified machinery that plays by the normal scope contract rules, that Unicycle object must behave like a “real” Unicycle object. Methods that she can invoke on a “real” Unicycle object must work as expected. instanceof tests must succeed. And so on.

Second, when she invokes a method on her received Unicycle object, it must, because of normal scope rules, somehow just-in-time find the “real” underlying Unicycle that is appropriate for the usage. In CDI, the “real” underlying Unicycle in this usage scenario will always be a contextual instance definitionally managed by a Context partially implementing the normal scope in question. We have seen how a Context supplies contextual instances, so we can see a glimmer of a way that this might be implemented generally. Then the method in question that the user invoked must arrange for this “real” Unicycle contextual instance that was found to receive the same method invocation in such a way that the user is none the wiser.

This is a classic example of proxying. A proxy in this general sense is a wrapper that (a) behaves as if it were a “real” object itself but actually (b) forwards all calls it receives to the “real” object it notionally wraps. Typically embedded within its innards is a strategy for finding the “real” object just-in-time (or perhaps it requires the real object to be supplied to it initially) and re-invoking on the “real” object whatever method the user invoked on it. Here, our user has taken delivery of a proxy that behaves just like a Unicycle but looks up the “real” Unicycle contextual instance just-in-time under the covers when a method is called on the proxy.

Client Proxies and Contextual References

A proxy object like this that implements these rules of CDI’s normal scopes is a very specific kind of proxy. It is known in CDI as a client proxy. A user who takes delivery of objects from upper-level CDI machinery receives client proxies when the lower-level machinery recognizes the Bean in play is affiliated with a normal scope. (There are some other edge cases where client proxies might also be involved, but we won’t cover them here.)

A client proxy always wraps, or delegates to, a contextual instance served up (definitionally) by a Context. A client proxy never wraps, or delegates to, another client proxy. As we’ve seen earlier, a Bean never creates a client proxy. We haven’t yet talked about what does create a client proxy, where exactly they come from, how long they live, how you might use one or detect that you are using one, or any of that, but we will soon.

A client proxy is one kind of two kinds of contextual reference. A contextual reference is either a client proxy or a contextual instance stored and supplied by a Context implementing a pseudo scope. Ordinary users doing ordinary things always interact with contextual references and ideally don’t know whether they are client proxies or contextual instances.

A caller can ask a BeanManager for a contextual reference. The getReference(Bean,Type,CreationalContext) method accepts:

  • a Bean (so that Bean can ultimately be supplied to a Context when contextual instances need to be retrieved)
  • a Type representing how that contextual reference will be used and a type that the contextual reference must implement
  • a CreationalContext which is not relevant for our purposes yet

(Additionally, the Type needs to designate a kind of contextual instance the Bean in question can create.)

The BeanManager will ensure that the right kind of contextual reference—properly implementing at least the supplied Type—will be returned. If the scope governing the lifecycle of the kind of reference to be returned is a normal scope, then the contextual reference that is returned will be a client proxy (that knows how to get the right kind of contextual instance when needed, and that forwards method calls to it transparently). If instead the scope is a pseudo scope, then the contextual reference that is returned will be a contextual instance. (Recall from earlier that the contextual instance may still be another kind of proxy, e.g. to handle interception and decoration, but it will never be a client proxy.)

Client Proxy Creation and Rules

When the contextual reference that is returned is a client proxy, CDI does not dictate how a CDI implementation must implement it, but does dictate precisely how such a client proxy must behave. It also imposes some restrictions on proxiable types to make it easier for CDI implementations to build it.

First, any Type that the client proxy must implement can’t denote a final class. This makes sense because one common way of implementing a proxy for a type is to extend the type in question and override its methods to find the “real” object and dispatch the relevant method invocation to it. Obviously if the methods of a given class are final, a CDI implementation cannot build a client proxy that overrides them.

Second, any Type that the client proxy must implement that is a Class (as opposed to an interface) must have a zero-argument constructor. This is so that a CDI implementation can actually create an instance of the class to be proxied, so that it can return it to the caller, and so that it is at least possible to do using something as simple as Class::getDeclaredConstructor. Remember, the client proxy itself is not a contextual instance. Rather, it is an object that wraps the machinery to find one and to delegate method invocations to it. It is not therefore managed by a Context. It is created “by hand” by the CDI implementation when needed. The constructor is allowed to be public, protected or package-level.

Some CDI implementations use proprietary methods to avoid even this restriction, but that behavior is not portable.

The most common strategy employed by CDI implementations to create client proxy classes is to use just-in-time bytecode generation. With this strategy, a CDI implementation typically has a repeatable algorithm to generate a proxy class name given the name of a “real” class and Bean information. If that generated class is not already found, a bytecode generation library such as ASM is used to generate a class with that name that extends the “real” class (or that implements the “real” interface) and plays by very specific rules.

Once the client proxy class is generated, it is instantiated in whatever way the CDI implementation wants to instantiate it. After all, it generated the code! Weld chooses to do this in a very flexible manner that I’ve written about previously. (The simplest way for a CDI implementation to do this is of course to simply invoke a zero-argument, non-private constructor reflectively, as noted above.)

Once this client proxy extending or implementing at least this particular Type is created, it is basically reusable, so most implementations choose to stash it away somewhere so that all this code generation and instantiation doesn’t have to happen again.

The client proxy so created now has to obey the rules that govern all client proxies. Specifically, it must, for every business method invoked on it:

  • Get the relevant contextual instance (the “real” object). We’ve seen how that works in general.
    • This can work here because at the time that the BeanManager::getReference call is made, and the client proxy class is generated, the Bean in question is supplied, so the generated client proxy code has access to the Bean‘s information and can save it away (Beans are immutable). This means it can find the proper Context from which to acquire the right kind of contextual instance because it can ask the Bean for its scope annotation, and can then ask a BeanManager for a corresponding active Context.
    • We also know that it is the responsibility of a Bean to perform dependency injection, interception and decoration (if applicable), though we still haven’t delved into those topics yet. So when the contextual instance is “loaded” by the innards of the client proxy, it is fully ready for business.
  • Invoke the method in question on the contextual instance. There’s no further processing that happens.

You can see from these (very simple) rules that any logic related to interception, decoration and dependency injection must be located in the Bean‘s create method, as noted several times above. That is, client proxies are quite straightforward and just dispatch method calls. They doesn’t do any interception or further proxying themselves.

So much for contextual references and one of their subtypes (client proxies). The main takeaway is: If a user calls BeanManager::getReference, all the hard stuff is handled for her.

Acquiring Contextual References in Beans

Let’s circle back all the way down to the lowest level again and look, again, at the lowly Bean and, this time, at its create method. We’ll do this because, recall, dependency injection must be performed (if it is to be performed at all) in this method, and to “do” dependency injection in CDI a Bean will need to acquire contextual references (the dependencies to inject), which we’ve just learned about.

As we’ve seen, the Bean::create method can do whatever it wants to make a contextual instance. We’ve also seen that there is a method on BeanManager that allows the acquisition of contextual references for a given Bean and Type.

It doesn’t matter who is authoring a Bean implementation. It could be an ordinary user, who is using CDI’s portable extension facilities to install that Bean into the CDI implementation, or it could be the CDI implementation itself, when everything starts up and it inspects annotated classes for relevant annotations and creates Bean objects to represent them. All Beans in the system use their create methods to create contextual instances.

Usually a Bean can get access to a BeanManager from within its create method. For example, when the CDI implementation itself is creating a Bean object, often it installs a BeanManager into its Bean implementation. Or in a custom Bean put together in a portable extension, often a BeanManager is available as a “reachable” object in the enclosing portable extension method. Regardless, what is important is that it is relatively trivial for a Bean to get its hands on a BeanManager inside its create method.

Let’s consider a Bean implementation that a CDI implementation builds, i.e. not a custom Bean installed via an end-user portable extension, but one built as part of the CDI implementation itself to represent an annotated class. Let’s say the Bean in question is the one that was creating Unicycle instances in our earlier example.

With just the tools covered above, even if the Unicycle class has a constructor that takes a Wheel object, you can see—perhaps faintly—that using the BeanManager the CDI implementation vendor employee implementing this Bean create method can:

  • first call BeanManager::getReference on the available BeanManager and pass in Wheel.class as the Type. Assuming she can also use that BeanManager to find a Bean that makes Wheel-typed contextual instances, she can pass that Bean too to the getReference call, and she’ll get back a Wheel-typed contextual reference as we’ve discussed above, that she knows will be suitable for this usage point, regardless of what scope the Wheel may belong to
  • then call the ordinary constructor on the Unicycle class that takes a Wheel object and supply it with the contextual reference she just acquired
  • then return the plain simple Unicycle object as-is (assuming, for simplicity, that interception and decoration are no applicable here).

Note that the only slightly odd thing this user has to do is acquire a contextual reference to a Wheel so that she can then stuff it in the Unicycle constructor. She didn’t have to generate any bytecode or do anything magic with proxies or any of that. If some other user now asks a BeanManager for a contextual reference implementing the Unicycle type, they’ll get a contextual reference to this Unicycle contextual instance. If the scope in question for the Bean in question is a normal scope, then automatically the contextual reference they receive will be a client proxy.

More to come.

Weld and Client Proxy Creation

(Taking a break from my blog post series in progress to write down stuff that I stepped through today on how Weld creates client proxies.)

The CDI specification says that if you have a managed bean in a normal scope (think: class with something like @ApplicationScoped or @RequestScoped on it), it must have a non-private, zero-argument constructor (and must not be final) so that a CDI implementation can proxy it.

You may have noticed when using Weld’s implementation of CDI SE that this seems not to be required. I can do this:

@ApplicationScoped // normal scope
public class B {
  private B() {} // hmm, seems to violate specification
  @Override public String toString() { return "B"; }
}

…and can inject an instance of that wherever I like:

@Dependent
public class A {
  @Inject
  public A(final B b) { // hmm; how does CDI/Weld make b?
    super();
    System.out.println(b); // you'll see "B" on the console
  }
}

Here is how that works.

When Weld’s CDI SE implementation starts up, it looks for a configuration item that indicates relaxed construction. This can be supplied in a few different ways, but the easiest way to supply it is by setting the org.jboss.weld.construction.relaxed System property to a textual representation of a boolean value (i.e. “true” or “false“). In Weld’s implementation of CDI SE, if you do nothing, the value of this configuration item is effectively true. In Weld’s implementation of CDI as found in application servers, the value of this configuration item is effectively false. This is worth noting.

First, the easy path: if for whatever reason relaxed construction is not enabled, then we stop here. My example above will fail and Weld will correctly tell you that it has no way to create a B instance because B is “unproxyable [sic]” according to the rules laid out by the specification.

Let’s assume that relaxed construction is enabled. Weld begins by looking for a ProxyInstantiator implementation:

https://github.com/weld/core/blob/be7382b01c4a56c54f92873c1c2ebf0445714bfe/impl/src/main/java/org/jboss/weld/bootstrap/WeldStartup.java#L335

That causes the create method to be called on the ProxyInstantiator.Factory class with access to the configuration subsystem:

https://github.com/weld/core/blob/151e1fedcc16d6d2dfec3ecdf1c095f75fdd995d/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyInstantiator.java#L128-L129

The create method begins by assuming that the ProxyInstantiator that will be used is the DefaultProxyInstantiator:

https://github.com/weld/core/blob/151e1fedcc16d6d2dfec3ecdf1c095f75fdd995d/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyInstantiator.java#L90

Then, if relaxed construction is enabled (which it is in this example), Weld will try two other hard-coded implementations in order, using the first “valid” one (we’ll see what that means shortly):

https://github.com/weld/core/blob/151e1fedcc16d6d2dfec3ecdf1c095f75fdd995d/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyInstantiator.java#L91-L103

The first of these implementations is the UnsafeProxyInstantiator, whose instantiation strategy is to use the sun.misc.Unsafe class (redirected in modern JDKs to the jdk.internal.misc.Unsafe class) to create an instance of a class without using constructors at all:

https://github.com/weld/core/blob/151e1fedcc16d6d2dfec3ecdf1c095f75fdd995d/impl/src/main/java/org/jboss/weld/bean/proxy/UnsafeProxyInstantiator.java#L47-L49

This is worth noting because you might be logging proxy instantiation inside your zero-argument constructor, but if this strategy is selected for whatever reason, your constructor won’t be called. I’ve personally been burned by this and have now seen others burned by it as well.

If that UnsafeProxyInstantiator class is not available or can’t be used for any reason, then a second non-standard ProxyInstantiator implementation is tried instead, which uses sun.reflect.ReflectionFactory under the covers (which in modern JDKs is sort of redirected to jdk.internal.reflect.ReflectionFactory). This class will happily use a private zero-argument constructor:

https://github.com/weld/core/blob/151e1fedcc16d6d2dfec3ecdf1c095f75fdd995d/impl/src/main/java/org/jboss/weld/bean/proxy/ReflectionFactoryProxyInstantiator.java#L52-L60

(In this case of course your private zero-argument constructor will be called so any logging you do in there will show up.)

(You can see how it does this here:)

Finally, if neither of these non-standard instantiation strategies works, then the already-constructed DefaultProxyInstantiator is used instead, which does what you think it does, and adheres to the standard:

https://github.com/weld/core/blob/be7382b01c4a56c54f92873c1c2ebf0445714bfe/impl/src/main/java/org/jboss/weld/bean/proxy/DefaultProxyInstantiator.java#L42-L44

That is how the proxy object itself is created. Note that this does not create the actual underlying instance. For that, a private constructor is just fine (in Weld’s CDI implementations, anyway).

Note also that the underlying instance is not created until a business method on the proxy is invoked. Note as well that any method defined by java.lang.Object, other than toString(), is not considered a business method.

Hopefully this helps someone!

CreationalContext Observations

Here are some random observations concerning CreationalContext, a funky little architecturally polluting blemish on the surface of CDI’s otherwise pretty good set of APIs. (I’ve written before on this little nugget.)

There is no documentation that says what a CreationalContext is. The class javadoc reads, in total:

Provides operations that are used by the Contextual implementation during instance creation and destruction.

So its purpose is exactly that of its two operations, one of which (push()) can be properly implemented as a no-op as we’ll see below. That means its purpose is solely to house the release() method.

To portably create a CreationalContext, you use BeanManager#createCreationalContext(Contextual). For the purposes of destroying dependent objects, which is the interface’s sole documented purpose, the supplied Contextual is never used.

A CreationalContext is architecturally tightly coupled to a Context implementation for the Dependent scope. If you implement one, you have to implement the other because there is no portable way for an arbitrary Context implementing the Dependent scope to indicate to a CreationalContext that a dependent object needs to be tracked for subsequent destruction by the release() method. But in Weld you cannot supply your own instance of a Context for the Dependent scope, because the Weld-supplied one is always active, and there can be at most one active Context for a scope, and there is no way to remove a Context. So therefore you cannot supply your own implementation of CreationalContext in Weld unless you couple it to Weld interfaces and abstract classes…in which case why are you supplying one in the first place?

Weld implements CreationalContext by constructing a tree of them: each one tracks dependent objects added by its child. This means that Weld’s CreationalContext implementation is also tightly coupled to Weld’s implementation of BeanManager: every time a contextual reference is acquired, whether via injection or programmatically, a new “child” CreationalContext is created. This tree structure is not necessarily needed to perform dependent object cleanup (since, for example, OpenWebBeans implements CreationalContext without such a tree structure). The result is that in Weld many CreationalContextImpl objects get created that do nothing.

push() and release() have nothing to do with each other. In fact you can pass the TCK by implementing push() as a no-op. Many developers you talk to think that these methods are related. Almost nobody knows how to use them properly. You are, it turns out, supposed to always (probably within a finally block) call release() as the last thing you do in a custom bean’s destroy() method. Otherwise it is possible that your program will leak memory.

release() means, simply, “destroy dependent objects tracked by this CreationalContext“. Of course it may not be exactly this CreationalContext, because it might be a tree of such CreationalContexts. Or maybe it’s “destroy all dependent objects reachable from the creation of whatever it was that caused this CreationalContext to come into existence”. No specification language indicates whether release() must be idempotent. Obviously it would sure be nice if it were, so CDI implementations tend to make it so.

Remember that according to the specification a CDI implementation can destroy an unreferenced dependent object at any point by any means for any reason, so strictly speaking release() isn’t really a method that should have ended up in the specification (it’s an implementation detail). It’s clearly convenient so maybe that’s why it ended up in here.

The only time you need a CreationalContext is when you know that a contextual instance is going to be created. If you know that a contextual instance already exists, then the CreationalContext will never be used by the Context#get(Contextual, CreationalContext) method.

I often wonder why instead of this strange API there wasn’t a DependentContext interface, extending Context, that would allow you to add and destroy dependent object hierarchies, since we already know that Dependent is a special scope. There’s probably a good reason but I can’t think of what it is at the moment.

CreationalContext Deep Dive

What is a CreationalContext in CDI?

A perfect example of how naming things is the hardest problem in software engineering, really. The only method that it exposes that anyone should really be concerned with, release(), is used at destruction time, and has nothing to do with creating anything.

Here’s how I would describe it:

A CreationalContext is a bean helper that automatically stores @Dependent-scoped contextual instances on behalf of some other bean that has references to them, and ensures that they are cleaned up when that bean goes out of scope.

That’s basically it.

Consider a bean, B, that has a reference to a @Dependent-scoped bean, D. In Java terms, it might have a field like this:

@Inject
private D d;

Now, if the Bean implementation that created this B contextual instance has its destroy(T, CreationalContext<T>) method called, then B will be destroyed. B, in other words, will be the first argument.

When B is destroyed, you want to make sure that its dependent objects are also destroyed. But you also don’t want to burden the programmer with this. That is, you don’t want to make the programmer have to jump through some hoops inside B‘s logic somewhere to say “oh, when I’m destroyed, make sure to arrange for destruction to happen on my d field”. That should just happen automatically.

To allow this to happen automatically, CDI locates this logic inside a CreationalContext (yes, a “creational” context, even though we’re doing destruction. Naming is hard.). At the moment a CreationalContext is released, it has “in” it:

  • A bean that it is helping (usually)
  • A set of dependent instances that belong to the bean that it is helping
  • For each of those dependent instances some way to tie it to the Contextual (the Bean) that created it

When release() is called, the CreationalContext iterates over that set of dependent instances and their associated Beans and calls destroy() on each of those Beans.

So the programmer didn’t have to do any of this work. She just @Injected a D into a field and even if D is some sort of custom object it gets destroyed properly.

(It all follows from this that release() implementations must be idempotent and pretty much should never be called except from within a destroy() method of a custom bean. They also must work on only the bean that is being helped, and not on every dependent object “known” to the CreationalContext.)

OK, that’s all fine, but how did all these objects get “into” the CreationalContext in the first place?

When B was created, via a Bean‘s create(CreationalContext<T>) method, the container supplied that method with a new, empty CreationalContext that is associated with the Bean doing the creating. That is, prior to the create call, the container called beanManager.createCreationalContext(beanThatIsCreatingBInstances), and the resulting CreationalContext is supplied to beanThatIsCreatingBInstances‘s create method as its sole argument.

What does a custom Bean author here need to do with this CreationalContext as she implements the create method? The answer is: ignore it completely. That’s easy.

(More to the point: push(Object) does not, as you might be tempted to believe, stuff a @Dependent-scoped object into the CreationalContext such that release() will have any effect on it. The two methods are completely orthogonal. Around this point you should start getting suspicious: how does a dependent object get “into” an arbitrary CreationalContext anyway? An excellent question.)

In the case of managed beans—ordinary CDI beans, with @Inject annotations and whatnot processed by the container without any special funny business—remember that the container will take care of satisfying the injection points. So in the case of B with a D-typed d field injection point, the container will arrange for a D-type-producing bean to be invoked and then will automatically arrange for that dependent object to be stuffed into the CreationalContext.

That’s a lot to take in. Let’s try to break it down.

Recall that the container created a brand new CreationalContext to serve as the bean helper for B when it is about to call B‘s create method.

In order to “make” a B, the container is going to have to satisfy its D-typed injection point (the d field in our example).

To satisfy the D-typed injection point, the container will need to find out what scope is in effect. It will discover that the scope is @Dependent (since our example says so; presumably D is annotated with @Dependent which allows the container to call BeanManager#getContext(Class<? extends Annotation>)).

With the right Context in hand, the container will ask it for an appropriate D instance. The method that the container uses here is Context#get(Contextual<T>, CreationalContext<T>). Here, the container does not create a new CreationalContext. It passes the CreationalContext it has made for creating the B instance. That’s important.

A Context is responsible for doing basically whatever it wants to return an instance, so long as if a new instance is required it results (ultimately) from the return value of Contextual#create(CreationalContext<T>).

The @Dependent-scoped Context is obliged to create a new instance with every request, so it will dutifully invoke Contextual#create(CreationalContext<T>) and get back a new D instance. (If we pretend for just a moment that D is made by some kind of custom bean, the custom bean author never had to touch the CreationalContext when she implemented the create method. She probably just returned new D() or something similar.)

OK, so now the Context has possession of a new D object. But before it hands it back to the caller, it is going to stuff it in the supplied CreationalContext as a dependent instance. After all, the @Dependent-scoped Context always produces dependent objects that are tied to some “higher-order” bean, and we know that this is what CreationalContext instances are for: to store such dependent objects together with their referencing bean.

So it’s fine to say all this, but how does the @Dependent-scoped Context implementation actually add a dependent object to the CreationalContext? We’ve already seen the push(Object) method is not for this purpose.

It does it via proprietary means.

Weld, for example, does it via casting. This can get interesting since a user can supply her own @Dependent-scoped Context implementation: in order to add dependent objects herself she must tie her Context implementation to Weld.

You might think you could have your own @Dependent-scoped Context implementation that arranges for a CreationalContext to be used as a key into a Map of this kind of state. Then you wouldn’t be bound to a particular implementation of CDI. But of course if someone calls release() on a CreationalContext, you would have to somehow arrange to be notified of such a call, and that’s impossible.

So the upshot is that the CDI vendor, who returns CreationalContext implementations from BeanManager#createCreationalContext(Contextual<T>), is the only one who can supply any @Dependent-scoped Context implementations, no matter what the specification says.

Returning back to what the end user should “do” with a CreationalContext: the answer is basically ignore it. If you are writing a custom Bean implementation, then as the last operation in your delete implementation you can do this:

if (cc != null) {
  cc.release();
}

Otherwise, just leave the thing alone.

Decoding the Magic in Weld’s Instance Injection

I went down this rathole today and wanted to write it down.

In CDI, let’s say you have an injection point like this:

@Inject
@Flabrous // qualifier, let's say
private Instance<Frobnicator> flabrousFrobnicators;

The container is obligated to provide a built-in bean, whatever that is, that can satisfy any injection point whose raw type is Instance.

If you think about this for a moment or two you’ll realize that this is really weird. The container cannot possibly know “in advance” what injection points there will be, and so can’t actually create one bean for a @Default Instance<Frobnicator> and another for a @Flabrous Instance<Frobnicator>. So somehow its built-in bean has to be findable and appropriate for any possible combination of parameterized type (whose raw type is Instance) and sets of qualifiers.

Weld solves this problem by rewriting your injection point quietly on the fly (or at least this is one way to look at it). This was quite surprising and I was glad to finally find out how this machinery works.

For example, in the code above, as part of my injection point resolution request I have effectively said: “Hey, Weld, find me a contextual reference to a contextual instance of the appropriate bean found among all beans that are assignable to an Instance<Frobnicator>-typed injection point and that have the @Flabrous qualifier among their qualifiers.” Of course, Weld cannot actually issue the bean-finding part of this request as-is, because there is no such bean (how could it possibly pre-create an Instance<Frobnicator>-typed bean with @Flabrous among its qualifiers?). So how does this work, exactly? Something must be going on with @Any but it’s nowhere to be seen here and isn’t applied by default to injection points.

It turns out Weld recognizes a class of beans that they call façade beans for which all injection requests are effectively rewritten (during the bean-finding part of the resolution process). Instance is one kind; Event is another; Provider is another and so on—you can see why they’ve decided these are special sorts of things.

At any rate, when you ask for a façade bean, the request that is made for the bean itself uses only the @Any qualifier, no matter what you’ve annotated your injection point with. All beans, including built-in ones, have the @Any qualifier, so the one true container-provided Instance bean will be found. And there’s our answer.

OK, that’s fine, but in the example above now we have a qualifier, @Flabrous, that we actually want to use, or we wouldn’t have gone to all this trouble. How does that get applied, given that it is ignored in the bean sourcing part of the injection resolution request?

Weld has tricked its own innards into supplying what is technically an inappropriate bean—it pretended that we asked for an @Any-qualified Instance<Frobnicator> bean even though we didn’t—but now that it has it, it can ignore whatever qualifiers the bean bears (@Default and @Any, as it turns out, and none other) because they’re no longer relevant once the bean is found. All that matters now is contextual instance mechanics.

Because Instance and Event and Provider and other façade beans are required to be in @Dependent scope, it turns out that the current injection point is available and can be used internally by the bean itself to find out what qualifiers are in effect so that it can create an appropriate contextual instance. And that’s exactly what happens: the bean supplied by Weld is an extension of AbstractFacade which uses the injection point to determine what qualifiers are in effect.

This whole process is of course deeply weird and I’d imagine that it or derivative effects rely on a hard-coded list of façade beans somewhere. Sure enough, here’s an example of the sort of thing I mean.

Another way to approach this sort of thing might be to introduce a super-qualifier or something instead that says, hey, if a bean is qualified with this super-qualifier then it matches all qualifier comparison requests (which is really what’s going on here).

Anyway, I hate magic and am glad to have found out how this works!

A CDI Primer: Part 4

In the previous post, we learned that the only Contextuals that matter, really, are Beans, and we learned a little bit about injection points and loosely how they’re filled.

In this post we’ll look at how CDI actually discovers things, and how it normalizes them into Bean implementations, and how it marries them with Context implementations to figure out what their lifecycles are going to be.

The Container Lifecycle

CDI has a very well-specified lifecycle.  There is a general startup phase during which all the raw materials in the world are discovered, arranged and pared down to form a network of Bean implementations that produce and consume each other.  Once that startup phase has completed, the actual application—whatever it might be, that makes use of all these producers and consumers—starts, and runs, and does its thing.  Then there is a shutdown free-for-all where all Bean implementations can, indirectly, get a chance to clean up, and that’s all there is to it.

But what are you, the end-user, the ordinary developer, supposed to do with all this?  In your hand, you have a class that has some injection points in it (fields or methods annotated with Inject), and you want them filled.  What does this have to do with Bean implementations?  After all, your class doesn’t implement Bean.  We’ll see how internally, in a way, it sort of does.

Discovering Things

As part of the startup phase, CDI performs type discovery and bean discovery.

Type discovery is a fancy name for taking stock of what classes exist on the classpath.  Plugins, called portable extensions, can affect this; that’s a subject for another day.  For now, know that CDI will scan the classpath for particular classes and will add them to a set of such classes that represents its type world.

Once types have been discovered, CDI performs bean discovery, where some of those types it found lying around are normalized into Bean implementations internally.

It’s important to realize what’s going on here.  For the typical developer scenario, most classes that are discovered are turned into producers.  This can be a little counterintuitive—I don’t know about you, but that’s not usually what I think of when I have a class in my hand named with a noun, like Person or Customer.  Really?  Customer is a producer?  A producer of what?  Well, of instances of itself, it turns out.  Which of course we all actually know, because it has a constructor.

Managed Beans

So consider our ongoing stupid example of a Backpack class, with a simple zero-argument constructor, annotated with Singleton, and a Gorp-typed field annotated with Inject.  Let’s say that CDI discovers it.  Internally during bean discovery CDI creates a Bean to represent it:

A Bean implementation built internally like this is called a managed bean, and the class itself is frequently called a managed bean as well.

It’s important to realize that for a given managed bean one of its bean types and its bean class are always identical.

Producer Methods

Another very common kind of bean is a producer method.  In this case, CDI has done its type discovery, and has found a class called CandyShop also annotated with Singleton (I’m picking Singleton because it is a scope that everyone is intuitively familiar with.)  Let’s say this class has a method in it declared like this:

@Produces
@Singleton
public Candy produceCandy() {
  return new Candy();
}

This time, CDI will create a Bean internally for CandyShop that looks a lot like the one above, namely:

But then it will also create a Bean internally that represents the producer method:

Do you see that the bean class here is CandyShop but the getTypes() method returns a Set of bean types that includes Candy.class, not CandyShop.class?  The takeaway here is that usually when you’re considering a true CDI bean you are, as a normal developer, interested in one of its bean types, not its bean class.  In other words, you’re interested in (in this example) Candy.class, and normally not so interested in the fact that the producer method that creates its instances happens to be housed in a class called CandyShop.  The terminology in the documentation certainly does its best to make this about as clear as mud.

Producer Fields

Just as you can have a producer method whose bean class is one thing while its bean types are another, you can have a producer field.  Let’s say our CandyShop class from the example above also has a field in it declared like this:

@Produces
@Singleton
private PeanutButter peanutButter;

Once again, CDI will create a Bean for CandyShop, just as it did before, and here it will also create another Bean:

In practice, producer fields are comparatively rare.  They exist primarily to bridge the worlds of Java EE, where you might have a field that is annotated with Resource (so is being set by some kind of JNDI-aware machinery), and CDI where you can have the very same field annotated with Produces.  This lets CDI set up a Bean implementation under the covers that creates instances from Java EE-land without any other aspects of the CDI ecosystem really being aware that Java EE is even in the picture.

Decorators and Interceptors

Two other primary Bean implementations are Decorators and Interceptors.  I’m not going to talk about them because although it may look like it by this point I’m not writing a book.  Suffice it to say they are represented in the CDI ecosystem by Beans, and so are inherently producers of things, which can also be counterintuitive.

Custom Beans

Finally, without digging deep into portable extensions, we can at least say that portable extensions have a variety of ways to cause a Bean implementation to be created by hand at container startup time.  When Beans are added into the system this way, the portable extension has absolute full control over them.

Putting It Together

The biggest takeaway here is that everything in CDI is a Bean.  In the documentation, almost everything is a little-b bean.  A bean, represented by a Bean, is fundamentally a producer of something.  There are recipes that we’ve just enumerated that translate ordinary Java constructs into Bean implementations when bean discovery is performed: a creator and a destroyer (Contextual) together with bean types and a scope (BeanAttributes), a hosting bean class and a set of injection points (Bean).

There’s another thing that falls out of this.  Bean is a parameterized type: you have a Bean<T>.  The <T> is, however, always usage-specific, because it comes by way of Contextual, whose usage of its type parameter is the return type from its create method.  That is, <T> represents one of a Bean‘s bean types—one of the kinds of things it can make—not its bean class—the class hosting the producer method or constructor.

Consider a Bean<Person>.  Because a Bean<Person> is a Contextual<Person>, it follows that you can call its create method and get a Person back.  But it does not follow that calling its getBeanClass() method will return Person.class!  Perhaps the Bean<Person> you are looking at represents a producer method, or a producer field, for example.

Finally

So finally we can see how CDI makes @Inject work, which was what we set out to do in part 0:

  • CDI discovers types
  • For each type found during type discovery, CDI creates a Bean to represent it, or at least tries to
  • For each producer method and producer field (and other cases), CDI creates another Bean to represent it
  • For every InjectionPoint found in this pile of Beans, CDI performs typesafe resolution to see what Beans have bean types that “match” the InjectionPoint‘s type
  • Assuming that all slots get matched up to producers, whenever CDI needs to obtain an instance of something, it does so through the right Context which is in the business of handing out contextual instances
  • CDI can find the right Context by checking out the scope available from each Bean
  • Ultimately the Context, when asked to produce an instance of something, will call through to a Bean‘s create method

I’ve deliberately left out qualifiers, which are extremely important, but are deserving of their own article later.

There’s much more to say about CDI, but I think I’ll stop there for now.

Thanks for reading this primer!

A CDI Primer: Part 3

In the previous post, we learned about typesafe resolution (the process of matching producers (Contextual implementations) with consumers) and where, exactly, Contexts fit in.

We also learned that you can “label” a Context with a scope, an annotation class standing in for the kind of lifecycle you want a Context whose getScope method returns it to implement.

We also learned that in some unspecified way you can apply the same annotation to a Contextual implementation.

The net result was that we sketched out our first hazy picture of how a Gorp-typed slot in a consumer (Backpack) might receive a singleton Gorp produced by a Contextual implementation whose type parameter is Gorp.  (If you’re wondering what all this is about, I heartily recommend you start at the beginning with part 0.)

Nevertheless, as we did this, we waved our hands furiously over certain details.  Specifically, while describing typesafe resolution, we made many references to CDI linking together producers and consumers without describing exactly how this happens, and we spoke a lot about Contextuals, but never really covered what they are, exactly.  We’ll look into that in some detail in this article.

Contextual Implementations: Beans

Throughout this series of articles, we’ve talked about Contextuals as being CDI’s implementation of producers in the dependency injection mindset (which we described in part 0).

Contextuals produce contextual instances.  And contextual instances are what Contexts supply to fill @Inject-annotated slots.  You get all that by this point I’m sure.  But we haven’t discussed what Contextualare.

Strictly speaking, of course, a Contextual implementation only has to implement the create and destroy methods.  Great.

Let’s say you write a two-method-long class that does that.  Now what?  Nothing, that’s what.

It turns out that CDI doesn’t really give you an “in” using this interface: you can compile a Contextual implementation, stick it somewhere, and it will happily sit there until the end of time waiting to be discovered and used, which will never happen.

But a subclass (subinterface) of Contextual is Bean, and we’ve all heard that term before.

As it turns out, the only direct subtype of Contextual that CDI inherently knows about is Bean.

So in most cases where I’ve written about Contextuals, you can substitute Beans, and be just fine.  A Bean “is a” Contextual, and CDI deals primarily in Beans.  (There are mechanisms throughout CDI for getting Bean implementations “into” the system, but none for directly getting “raw” Contextuals that are not Beans into the system.  We’ll cover this interesting structural fiesta below.)

So if that’s all true, why have I been talking about Contextuals all this time, and not Beans?

Because Contextual is the part of the Bean interface that deals with production (it consists solely of create and destroy methods, after all).  The rest of the Bean interface, as we’ll see, deals with other things.

We’ve backed into this series of articles from the production end: we have been shining a light on exactly how “CDI makes @Inject work”.  So production has been front and center, and that’s what Contextuals give you.

Now with the production facet of Beans under our belts, we can turn our attention to the other facets.

Let’s start with one such facet—the BeanAttributes interface.

BeanAttributes

CDI was defined originally back in an era where inheritance was used a lot, and composition…not so much.  As a result some compositional concerns in CDI are expressed—conveniently but a little opaquely—in terms of inheritance.  This is true of the trio formed by Bean, BeanAttributes and Contextual.  Luckily we can tease them apart.

Here is a class diagram showing that Bean inherits from both Contextual and BeanAttributes:

CDI Primer 3

This is certainly obviously how the interfaces are actually structured, but it hides the more important fact that each of the collections of methods defined by each interface is really a facet of the same underlying object.  With only a few rare exceptions, CDI assumes that the object “behind the curtain” of a Contextual interface, for example, will also implement Bean.

That is, a Bean “is a” Contextual, sure, but really a Bean “has a” Contextual facet: it has a facet that deals with production.  We’ve covered Contextual extensively.

A Bean also “is a” BeanAttributes, but really, again, Bean “has a” BeanAttributes facet: it has a facet that deals only with discovery- and typesafe resolution-related concerns.  (You’ll note in particular that the T type parameter used by create and destroy is not used anywhere in the BeanAttributes interface!)

A BeanAttributes is a facet of a Bean that is concerned with its overall place in the CDI world.  We’ll look at its methods selectively and carefully, ignoring those that don’t yet make any sense.

(And finally the collection of methods defined by the Bean interface itself is a facet of a Bean implementation that is concerned with its role as a consumer.  We’ll cover this below.)

getScope()

The first BeanAttributes method of interest we’ll consider is getScope(), which returns an annotation class representing a scope.

Here we can finally see explicitly what we handwaved over in part 2: effectively in CDI, every Contextual implementation is always also a BeanAttributes implementation, so every Contextual is capable of essentially reporting which Context manages the lifecycle of its produced objects.  See part 2 for more on this.

This lets BeanAttributes that are producers (which is to say all of them, since in CDI’s ecosystem they’re all also effectively Contextuals) still have a say in the lifecycle management of their produced objects, but they don’t actually have to implement that management themselves.  Nice.

getTypes()

The next one is getTypes(), which reports the Set of Types that a producer can make.  Again, this method only makes sense when it is tacitly understood that BeanAttributes and Contextual are always facets of the same underlying object, i.e. that all BeanAttributes are always producers (Contextuals).

So, for example, if your Contextual implementation gets instantiated with a type parameter value of Object, then if your Contextual implementation is also a BeanAttributes implementation, as it should be, you can specify with this method exactly what subtypes of Object your create method produces.

CDI calls this method to gain insight into how to “fill” a consumer’s @Inject-annotated slot with an appropriately-typed contextual instance.  When trying to locate a suitable producer it can winnow the field by looking at the return value from this method and perform typesafe resolution using the results.  (For more on typesafe resolution, see part 2.)

Other BeanAttributes Methods

We’re going to table discussion of the other BeanAttributes methods for now, as they’re really another layer on top of these fundamentals.  We’ll come back to them in a later article.

Bean

Finally, the third facet of the Bean interface consists of the methods it defines itself apart from those defined by Contextual and BeanAttributesThese methods are related to a producer’s also being a consumer.

On Consuming Producers, Producer Classes and InjectionPoints

Back in part 0, we saw that there’s nothing wrong with a producer also being a consumer!  Producers frequently need to consume raw materials to do their jobs.

We also saw that producers come in many abstract flavors: methods, fields and constructors.

A producer also needs a “host class” (a method, field or constructor has to “live in” a class, after all), and in part 0 we decided to call such host classes producer classes for want of a better term.  (CDI calls them “bean classes” for reasons we are only now capable of understanding and which we’ll look into below.)

We’ve also talked throughout this article series about consumers and producers in terms of “slots” and “filling slots”.  I have a Backpack; it has an @Inject-annotated Gorp-typed “slot”; CDI performs automatic wiring and “fills” the “slot” with a contextual instance of Gorp sourced from the right Context by way of a Contextual implementation.  (We went into some detail on this example in part 1.)

In the spirit of less handwaving, let’s call these slots what they’re actually called in CDI: injection points.

An injection point is a slot that can be filled with a contextual instance.  It is a point at which CDI performs (dependency) injection.  Injection points are represented in CDI by the appropriately-named interface InjectionPointInjectionPoints have a type (and some other stuff, which we’ll cover another day).

So our Backpack consumer has a Gorp-typed injection point.

While it does not explicitly use these terms, CDI says that a consumer simply is something with InjectionPoints: it is a Thing With Slots That Have To Be Filled.

As we’ve seen, effectively all Contextuals—all producers—are also Beans.

And we’ve seen that a producer can be a consumer.

And finally we’ve seen that a producer is housed in a producer class, which I’ve told you CDI calls a bean class.

So it should come as no surprise that this consumer facet of a Bean is represented by two methods:

getInjectionPoints is pretty simple: it returns the set of “slots” that the producer needs values for in order to do its job.  If the producer is a method, for example, then the injection points will represent the method’s parameters.  If the producer is ultimately represented by a constructor, for a more complicated example, the injection points will represent possibly the constructor itself as well as any other @Inject-annotated fields and methods in the class.

getBeanClass is a little trickier, and is in my experience one of the most misunderstood methods in all of CDI.

​​getBeanClass()

getBeanClass returns the producer class, not the class of the thing being produced.

That is, if you have a producer that is a method, getBeanClass returns its “host class”—its declaring class—not the class of its return type.  This will become important when we talk about CDI producer methods.

Similarly, if you have a producer that is a field, getBeanClass returns its declaring class, not the class of the field.  This will become important when we talk about CDI producer fields.

Finally, if you have a producer that is fundamentally a constructor, obviously a constructor makes instances of its own declaring class, so getBeanClass will return the producer class, sure, but that will also be the class of the thing being constructed!  This will become important when we talk about the most common kind of Bean implementation found in CDI: the managed bean.

The most important things to take away from these CDI internals so far are:

  • CDI has many ways of discovering things, but all producers and consumers from the dependency injection mindset can be represented in CDI as Bean implementations
  • a Bean is fundamentally a producer of things, not the things produced, and a consumer only secondarily
  • all Contextual implementations normally found in a CDI application are Bean implementations too

Automatic Wiring (Almost Entirely) Demystified

Our picture of how CDI accomplishes automatic wiring just got a little clearer.  Every producer in the system now has a facility for reporting:

  • what kinds of things it makes (getTypes())
  • what Context the things it makes should “belong” to (getScope())
  • what it needs to do its job (getInjectionPoints())
  • what class it “lives in”, of which an instance might need to be produced for the producer to be invoked (getBeanClass())

If CDI could find Bean implementations in various flavors lying around, and then normalize them into true Bean implementations in memory, it could match the Gorp-typed InjectionPoint of the Backpack-typed Bean implementation to hopefully the one Bean implementation whose getTypes method contains Gorp.class in its return value.  It could then locate the appropriate Context implementation, by looking at the return value of the getScope method, and could ask that Context to get a Gorp.  It could then use the InjectionPoint to set the actual Gorp value.

That is, of course, exactly what CDI does.

In the next post, we’ll get rid of the remaining handwavy bits and will look at how CDI:

  • “normalizes” “Bean implementations in various flavors lying around” into “true Bean implementations in memory”
  • “locate[s] the appropriate Context implementation”
  • Uses “the InjectionPoint to set the actual Gorp value”

Thanks for reading along so far!

A CDI Primer: Part 2

In the previous post we covered Contexts and Contextuals and the relationship between them.  A Contextual, briefly, is the CDI representation of a producer (a CDI-independent concept within the dependency injection mindset we covered in part 0) focused solely on the mechanics of production, with no responsibility for caching or storage or any other kind of lifecycle management.  A Context is CDI’s façade of sorts for Contextuals that has no responsibility for making objects of a given kind—it uses Contextuals for that—but all kinds of responsibility for managing the lifecycles of those manufactured or acquired objects.

We also learned that contextual instances are effectively the return values from the Context#get(Contextual, CreationalContext) method invoked on a given Context (and by extension the return values of implementations of the Contextual#create(CreationalContext) method.)  If your class has an @Inject-annotated “slot” in it, and it gets “filled” by CDI, then you just took delivery of a contextual instance from a Context, created by a Contextual.

In this post we’ll start looking at the actual mechanics that CDI uses to match contextual instances to consumer “slots”, and the beginnings of how those pieces of the machinery are found in the first place.

A Digression on Java Generics

And now, for everyone’s favorite subject: Java generics.

First, some housekeeping.  I’m going to run right into the utterly awful WordPress editor which is schizophrenic about angle brackets.  Java generics feature a lot of angle brackets.  They disappear in WordPress.  (Using ampersand-lt-semicolon and similar SGML-entity-based “solutions” doesn’t work, because the helpful editor will expand it in place, then save the result, neutering the attempt to use them in the first place.)  So I’ll use curly braces instead.  Just squint a lot and you might even be able to see them as angle brackets.

Suppose I have a field whose type is List{Number} and you have a List{Integer}.  Can I take your List{Integer} and put it into my List{Number}-typed field?  No, I cannot.  You can learn more about this from the Java Tutorial if you need to.  This is a case of trying to figure out assignability of parameterized types (like List{Number} and Class{T} and so on).  In order to do wiring properly, you—or the magic system that is going to do the wiring for you, like CDI—have to get this right.

Now, if I have a field whose type is List{? extends Number} and you have a List{Integer}, that will “go into” my field just fine.  So the person or machine doing wiring has to take wildcards into account as well.

Typesafe Resolution

This process of accounting for all sorts of different types—simple-typed slots like fields with types like Number or complicated slots with parameterized types like List{Number}—and matching those slots to compatible types, such as the return types of all producers in the system, is known as typesafe resolution.  “Typesafe” here is meant to emphasize the fact that—unlike some other dependency injection frameworks such as the machinery that was in Java EE at the time—CDI matches types, not names: your @Inject-annotated field’s type is matched to a producer’s type.  (Earlier dependency injection frameworks used name matches, which are more brittle.)  “Resolution” refers to the fact that a consumer’s slot has been matched, or resolved, to a particular production type—and thereby to a particular dependency.

Let’s say that CDI can somehow find all the slots in my classes that need contextual instances.  And it can find producers that make all different sorts of contextual instances of all different sorts of types.  If there is exactly one producer in that big pile of producers (of any kind—constructor, method, field…) whose production type is assignable to a given slot, then we have a match: we say that typesafe resolution has completed successfully, and we know that that wiring can be set up automatically.  If I have a slot that asks for a Gorp, and there is exactly one producer that returns a Gorp (or a Gorp subclass), then as we saw back in part 1 we can just “see” that that producer should be called to fill that slot.  CDI can therefore also “see” that this is the case, so is able to make it work.

Unsatisfied Dependencies

What happens when there is no producer whose production type is assignable to my @Inject-annotated field’s type?  We say in this case that typesafe resolution failed because we have an unsatisfied dependency.  I asked for a Gorp , but there wasn’t any Gorp producer that could respond.  The wiring cannot be completed automatically.

Ambiguous Dependencies

What happens when there are lots of producers whose production types are all assignable to my @Inject-annotated field’s type?  We say in this case that typesafe resolution failed because it was ambiguous.  The wiring cannot be completed automatically.  Without further information, CDI can’t make a call on which producer to select to produce an object to go in the right slot.

Finding the Right Context

Let’s say that I have a class named Backpack with a field whose type is Gorp, and there is exactly one producer in the world (represented as always in CDI by a Contextual under the covers) in some handwavy unspecified fashion that returns Gorp, and so CDI in the abstract is able to at least conceptually connect the two—i.e. typesafe resolution succeeds.

While talking about typesafe resolution, we’ve been talking about consumers and producers (Contextuals), but we’ve quietly tabled any mention of Contexts.  Let’s bring them back into the conversation.

Recall that a Context is responsible for fronting a producer (a Contextual), and for deciding when and for how long to cache its results, and that it is a Context implementation that ultimately supplies dependencies, calling upon the services of a Contextual implementation when required.

Graphically, our little case might look like this, using UML notation:

ProducerConsumerContextClassDiagram

Here, I’ve colored the CDI internal interfaces gray, our application classes (Backpack and Gorp) cyan, and then have highlighted in pink and red respectively a hypothetical Context implementation and a hypothetical Contextual implementation.  I’ve also used «stereotypes» to help with keeping the terminology straight.  Once again I’m going to have to use curly braces in my text below instead of angle brackets thanks to the WordPress editor’s many flaws.

You can see that in general a Context uses a variety of Contextual implementations to serve dependencies.

You can also see that in this case there is a Some Context Implementation? that fronts a Some Contextual{Gorp} Implementation? that is the ultimate producer of Gorp instances.

The Context implementation is going to have rules in it about when to return the same Gorp instance and when to create a new one.

The Contextual{Gorp} implementation is the producer and is going to be concerned with how to make a Gorp instance.

These classes are components in the same way that our Backpack and Gorp classes are components.  There can be many Context implementations in the system, and there can be many Contextual implementations in the system, all supplying different types, and all blissfully unaware of who might be asking for those types.  Further, a Contextual doesn’t know what Contexts might be using it, and a Context doesn’t know what Contextuals there are in the world.

So how does CDI figure out which Context implementation to pick to serve up Backpack‘s Gorp dependency?  And, even if it somehow magically does that, how does it then also figure out that the Context in question should use a particular Contextual to “back” it?

You can see, I hope, that there must be some kind of a mechanism available to let CDI know at the very least how a Contextual implementation might be linked with a Context implementation.  That hinting mechanism is a CDI construct called a scope.

Scopes

If a Context implementation is where contextual instances used by consumers come from, then a scope is a construct that indicates to CDI that this Contextual over here “goes with” that Context over there.

That is, in a very abstract sense—and we’ll get concrete soon enough—you mark a Contextual in some way that lets CDI see from that marking that the Contextual “belongs” to a certain Context implementation.

So if there is a Context in the world in some kind of handwavy unspecified fashion, and it can somehow identify itself to CDI as a producer of singletons (let’s say), and you have a Contextual implementation whose returned objects you want to be singletons, then you brand your Contextual in a particular way that identifies it as belonging to the singleton Context implementation.

The shape that this mechanism actually takes in CDI is very simple.  A scope is a particular kind of annotation class.  (Scopes happen to be any annotation classes that are themselves annotated with either javax.inject.Scope or javax.enterprise.context.NormalScope, but for this discussion we don’t really care about that for the moment.)

Let’s keep rolling with our singleton Gorp case.

When we introduced Contexts, we focused exclusively on the get methods.  But there is another interesting method on Context.  It is getScope.

That method returns an annotation class that basically ends up labelling the Context implementation.  The Context can now be matched or looked up under this annotation class label.

So, for example, CDI happens to ship with a built-in Context whose getScope method returns javax.inject.Singleton.class.

On the “other side”, it turns out you can mark certain Contextual implementations with that same annotation.  We’ll see exactly what shape this takes a little later; for now just know you can do it.

So if our Contextual{Gorp} implementation is somehow annotated with javax.inject.Singleton, then CDI now has what it needs: it can find the Context implementation indexed under Singleton.class, and “link” it with the Contextual{Gorp} implementation annotated with that annotation.

Then, assuming that typesafe resolution has succeeded, as it would in our trivial example, CDI now knows that it can complete the wiring automatically: our Backpack class will make an implicit request of CDI’s built-in-Context-implementation-associated-with-Singleton.class, and that Context implementation will use the Contextual{Gorp} that was annotated in some handwavy way with @Singleton.  The circuit is complete.

Our Backpack can now take delivery of a Gorp and anyone else who asks for a Gorp will get back the very same Gorp instance, not a new one.

Enough Handwaving

We’ve done a lot of handwaving to get to this point.

  • We’ve handwaved over what Contextual implementations can look like.
  • We’ve handwaved over how CDI figures out what producers and consumers exist in its world.
  • We’ve handwaved over how CDI figures out what Contexts exist in its world.
  • We’ve handwaved over exactly when CDI performs all this discovery.

We’ve probably also handwaved over a lot of other stuff.

At least some of the handwaving will start to end in the next post!

A CDI Primer: Part 1

In the previous article, we dabbled briefly in looking at the surface of the iceberg that is the CDI machine for making @Inject work as a way of answering some basic questions about what, exactly, CDI does and why you might want to use it.

We also, much more importantly, looked into the dependency injection mindset.  We talked about abstract notions of producers and consumers and wiring them together.  We introduced the idea that if you look through the right lenses, fields, methods and constructors can all be producers housed in particular producer classes.  And finally we pointed out that producers can be consumers and vice versa.

Now let’s talk about lifecycles.

Object Lifecycles and “Producer Proxies”

When a producer of any kind “wants” to make or supply or acquire an object, two decisions have to be made:

  1. how to make or supply or acquire the object
  2. when to make or supply or acquire the object regardless of how that happens

Some producers, as we saw in the previous article, are, as often found in the trenches of enterprise Java development, what I’ll call singleton suppliers.  They acquire the (mostly!) One True Instance™ of the object in question somehow, sometimes creating it once if necessary, sometimes by interrogating some ancient snarling hairball of a legacy system, and then from that time forward in the whole life of the application, that’s the object you get if you ask them to supply it to you.

Other producers, like constructors, create a new object each time one is to be produced because they can’t do anything else, or they’re kind of uninterested in the ways that they might be called, so they shrug and say, hey, if you want a new object, call me; otherwise, don’t; I don’t store or cache nothin’.

What’s interesting about producers of any kind, in isolation, without any other technologies such as CDI or its subsystems in play, is: producers in isolation combine how an object is produced with when it is produced.

For example, what I’ll call singleton suppliers—those all-too-common “enterprisey” methods that somehow acquire a Singleton From Elsewhere™ and then return it when asked—are combining the mechanics of how the singleton is produced (maybe it’s looked up from some other system) with when it is produced (maybe this system lookup only happens once and then the result is stored as a static singleton).

Or constructors: if you acquire an object from a constructor—a kind of producer, remember—then no matter what you do and no matter what it does you’ll get a new instance of the produced object each time because that’s what constructors do.

What would be nice is to let producers do what they do—acquire or make things when called for—and have there be some other subsystem that controls when a produced object is handed to a consumer.  Something that can go “back to the well”—the producer “well”—when needed, but not when not needed, and is in full control of when that happens, but does not itself know how the manufactured items it is storing or caching are made.  Something that is kind of like a proxy for producers: something that can stand in front of them and hand out their results when appropriate, regardless of how they were made or from what system they were acquired, according to its own notions of lifecycle.

ProducerConsumerUseCase

In such a situation a producer can focus on how to acquire an object but not on how to cache it; a producer proxy can focus on when to cache an object, if at all, and when to clear the cache; a consumer, in grand dependency injection mindset fashion, can remain blissfully ignorant of both of these things.

Also in grand dependency injection mindset fashion, we want this producer proxy (my term, incidentally, not CDI’s) to not look up or acquire or otherwise scrounge around for its relevant producer(s).  We want it to simply declare somehow that it needs one, and then punt the problem of getting one to its caller (we’ll talk about who that might be in a moment).

CDI implements this producer proxy concept with a construct called a Context and it is the first CDI construct we’ll look at in depth.

Contexts…

The first thing to know about a Context is that as a CDI end user you’ll interact with it many, many times—and as a consumer you’ll never see it or know that’s what you’re doing.

A Context, in other words, is part of the internal CDI plumbing by which automatic wiring between producers and consumers is implemented.

A Context is the nexus where a consumer needing an object of a certain kind is wired in an abstract fashion to a producer that is capable of producing objects of that kind, and where the lifecycle of such a produced object is managed.

Inside the depths of CDI, when you mark a field or a parameter with @Inject, CDI asks a particular Context for the kind of object you want.  That Context, in turn, ends up asking a producer, when necessary, to make or acquire the kind of object that should go in your @Inject-annotated slot.

From the standpoint of a Context, a producer is represented by something kind of odd called a Contextual.  A Contextual is simply a producer that can also destroy the things it makes.  A Contextual can make any number of different things of a given type (so, for example, a Contextual whose type parameter is Object could make Gorp, Chocolate, PeanutButter or whatever).  Most of the time, though, a given Contextual makes one kind of thing.

Finally, a Contextual should not have, as its core concern, or any concern if at all possible, how long an object should live—it is a “pure” producer: it just makes ’em, ma’am, it doesn’t hang onto ’em.

Here is what the contents of the Contextual interface look like, in their entirety, and for now we can ignore the second of these two methods:


public T create(CreationalContext<T> creationalContext);
public void destroy(T instance, CreationalContext<T> creationalContext);

I hope you can see how simple that is.

Contextual is another one of those interfaces that is in the internals of CDI.  You rarely, if ever, implement it directly.  But you could.  And you do in some cases, usually indirectly, as we’ll see much later.

For example, ignoring CreationalContext—a subject for a later post—you could see that you might implement the create method in such a way that it wraps a constructor invocation (you’d be implementing a producer that is constructor-based).  Or you could see that you could implement the create method in such a way that it wraps a method invocation (you’d be implementing a producer that is method-based), though consuming other dependencies in this case might be a little trickier.  Or a field access.  And in many cases your destroy implementation might not have to do anything.

The takeaway here is that you can represent all producers as Contextuals of a particular kind.

Context, then, uses Contextuals to produce the objects it will then manage the lifecycle of.  Here are the (relevant at the moment) contents of this interface, and trust me when I tell you that for now we can ignore the second method:


public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext);
public <T> T get(Contextual<T> contextual);

Again, very simple.

The first method is the real workhorse.  It takes in a Contextual and a CreationalContext, as you can see.  Once again, we’ll ignore the CreationalContext.  (The second method is for certain cases where CDI wants to ensure that no creation at all happens: it just wants the Context to supply a cached instance if one exists; it doesn’t want the Context to make a new one.  We’ll ignore it for the sake of mental clarity.)

The first method’s contract is to acquire and return a T.  You’ll note that Context itself is not a parameterized type (it doesn’t have any angle brackets or type parameters in its name).  So you can see here that a Context can get a whole variety of different kinds of objects.

You can also probably squint and see that if I tell you (as I have) that a Context‘s responsibility is to manage the lifecycle of objects, not actually make them, then when it decides that it needs a new one it can (and should) just call the create method on the Contextual that has just been handed to it.  The Context knows “when”; the Contextual knows “how”.

If it already has an existing instance and has determined that this incoming demand can be satisfied by the existing instance, well, then it can just hand it back.

That’s all very convenient.  So a Context as a consumer remains blissfully ignorant of what kind of Contextual (producer) has been handed to it, and can use this raw material if it wants in order to fulfill its contract of supplying T instances.  And the Contextual can remain blissfully ignorant of lifecycle and caching concerns and can just return Its Thing™, whatever that might be, when asked to make it.

…and Dependency Injection

CDI stands for Contexts and Dependency Injection.  And now with the introduction of Contexts we have an incomplete and blurry view—but a view nonetheless—of how the major parts work together, and why “Contexts” is important enough to be listed in the title of the specification:

  • A consumer of some kind (your business-critical class) gets wired in some currently opaque-to-us way (involving @Inject) to a Context implementation that supplies it with the dependency it needs (via the Context#get(Contextual, CreationalContext) method).
  • The Context implementation gets wired in some opaque way to a Contextual implementation that knows how, but not necessarily when, to make those kinds of things.
  • A Contextual is a kind of producer but everybody but the Contextual implementation itself doesn’t know what kind.

The result is that CDI is now conceptually capable of injecting dependencies, taking into account desired lifecycles, and letting producers and consumers and producer proxies all focus on what they do best, and on nothing else.

Contextual Instances

I’ve spoken very loosely about producers making things of a particular kind.  And I’ve spoken equally loosely about consumers needing things of a particular kind.  And I’ve spoken just as loosely about the wiring process where a producer of a thing of a particular kind gets wired in some fashion to a consumer that needs those things, mediated by a producer proxy—a neutral term I invented to describe the lifecycle/lifespan-managing component that decouples when something is handed out from how it is made or acquired.

Now we’ve also learned that producers in CDI are represented by Contextuals and are effectively “fronted” by Contexts, and that producer proxies are represented by Contexts, and that Contexts therefore are the sources of instances that producers—Contextuals—make.  Consequently when a Context‘s get method hands you (indirectly) an object, that object is known throughout CDI’s literature as a contextual instance.  It is an instance of something that a given Context manages.

Still speaking loosely, when you ask for a Gorp to be supplied to you (injected) by CDI by using the @Inject annotation, you’re going to get a contextual instance of Gorp in the annotated “slot”.

Or, equivalently: if an object “comes out of” a Context, then it is a contextual instance, and its existence must be owed to the fact that CDI invoked get on a Context and the Context ultimately invoked the create method of a Contextual that produced it.  CDI “knows about” all contextual instances.  CDI does not know about (for the most part) objects that are not contextual instances.

In the next post, we’ll look at the mechanics of how CDI wires Contextual implementations that can make certain contextual instances of particular kinds to Context implementations that implement a lifecycle, and how CDI wires consumers of contextual instances to Context instances that can provide them.

A CDI Primer: Part 0

So many tutorials about CDI have been written I’m a little nervous putting down my own.  But here we are.

I believe that most of the CDI articles and posts I’ve read over my many, many years of programming don’t follow the right road for developers just starting out with CDI.  As a result, people think of CDI as magic.  Because its terminology is also unusual, misconceptions get built upon at the earliest stages of learning and you end up with developers sticking beans.xml files everywhere in a prayer to the gods to get their stuff to somehow work.

I also want to try to get the high level concepts in place first before diving deeper.  As a result, I’m going to speak a bit fast and loose here to start with.  My hope is that over time these foundations will demystify the great CDI machine.

Lastly, I’m primarily focusing on CDI alone, i.e. not on any aspect of its integrations with technologies like Java EE.

Let’s dive in.  We’ll start with a section that deals with CDI and @Inject, since that’s how most people first encounter CDI, but then we’ll move rapidly on to the dependency injection mindset, which is much more important.

CDI Makes @Inject Work

For anyone wondering “what is CDI? Why would I use it?” the quickest answer that makes immediate sense is:

CDI is the magic machine that lets you use @javax.inject.Inject.

OK, so why would I use @Inject?  What does it do for me?

Field Injection

Let’s say you have an instance field in your class, and you want it magically set to something, regardless of whether it’s public, protected, package-protected or private.

Do this:

@Inject // magic!
private Gorp myGorp;

CDI makes that work.

That is, some Gorp instance (we’ll talk about which one, and where it came from, in a bit) will get put there by CDI.  Cool!

Think a bit about this: you didn’t have to go hunting around for a Gorp instance yourself.  You didn’t have to look up what kind of Gorp to make from a properties file or JNDI or ServiceLocator or anything like that.  You asked for a Gorp, and a Gorp was delivered unto you from outer space.  Nice.  Simple.  Less of your code; therefore fewer bugs that will be assigned to you.  A smaller mental model: fewer second- or third-order concepts in your head means more clarity in programming the important stuff you need to do.

Injection is the overall term for this kind of magic: something comes along (CDI in this case) and injects a Gorp into, in this case, an instance field of your (business-critical, of course) class.  The thing that is being injected is a dependency: it’s something you need for some reason, so therefore whether you like it or not you depend on it.

So when you get a dependency injected into something, you have dependency injection.

We’ll call this particular case of injection field injection.

Where else can you use @Inject?

Method Parameter Injection

When CDI is in the world, you can also use @Inject on methods.  It’s the same kind of thing.  If you do this:

@Inject
private void consume(final Gorp gorp) {
  // nom nom
}

…the gorp “slot” will be filled with a Gorp instance (as before, we’ll talk about which one, and where it came from, and when in a bit) by CDI.  This is often referred to as setter injection, or setter method injection, or parameter injection, and you might think your method therefore has to be named something like setGorp, but it can be named anything.  The important part is that @Inject “goes on” the method.

Methods with @Inject “on” them can have as many parameters as you want.  CDI will try to “fill” all of them.  So if you do this:

@Inject
private void consume(final Gorp gorp, final Cheese cheese) {
  // nom nom nom nom
}

…CDI will “fill” the gorp “slot” with a Gorp instance, and the cheese “slot” with a Cheese instance.

Constructor Parameter Injection

CDI also makes @Inject on constructors work.  Constructors can be public, protected, package-private or private.  Just as with methods, @Inject-annotated constructors’ parameter “slots” will be “filled” by CDI.  So if you do this:

@Inject
private Chocolate(final PeanutButter peanutButter) {
  super();
}

…the peanutButter “slot” will be filled by CDI with a PeanutButter instance.

Making @Inject Work Is a Kind of Dependency Injection

This style of programming is lumped under the term dependency injection.  The idea is that you, the programmer, never look up or make or seek or acquire what you need (your dependencies).  Instead you “take in” what you need.

You force your caller to hand you your raw materials instead of hounding off and scavenging them yourself.  Always be lazy!

So if you’re writing a Chocolate, and you need a PeanutButter, you do not do this:

// Here is an example of a class that is *not* using
// dependency injection.  It is brittle and hard to test.
public class Chocolate {

  private final PeanutButter peanutButter;

  // Note that the constructor doesn't "take in" anything.
  // Yet the peanutButter field still needs to be "filled".
  // I wonder how that will happen?
  public Chocolate() {
    super();
    // You've seen this kind of thing in your job before.
    // There's the magic "look up the thing" method.
    // My experience has been that LDAP is usually involved. 😃
    this.peanutButter = lookupPeanutButter();
  }

  // Here is the magic "look up the thing" method.
  private PeanutButter lookupPeanutButter() {
    // Almost always there's LDAP or a singleton being used. 😞
    final GroceryStore singleton = GroceryStore.instance();
    // When this lookup breaks, was it because the GroceryStore
    // couldn't be found? or the PeanutButter? You will see
    // anti-patterns like this throughout enterprise Java
    // programming.
    return (PeanutButter) singleton.get("Peanut Butter");
  }

}

In the class above, really what you need is a PeanutButter.  It doesn’t really matter where it came from, just that you “take it in”.  So whether or not you’re ever going to use CDI or Spring or anything else, please write your class like this instead:

public class Chocolate {

  private final PeanutButter peanutButter;

  public Chocolate(final PeanutButter peanutButter) {
    super();
    this.peanutButter = peanutButter;
  }

}

What’s nice is that your class has now punted the problem of how to acquire the PeanutButter to the caller.  Now the caller has to figure that out.  Your Chocolate class is much simpler and easier to deal with.  As someone experiencing the glories of your world-changing code for the first time, I can understand it better and marvel more at your brilliance.

If, on top of this well-designed class, you now put @Inject in the right place, then CDI’s magic can supply—inject—the PeanutButter.  That is, CDI becomes the caller:

public class Chocolate {

  private final PeanutButter peanutButter;

  // Let's use constructor parameter injection
  @Inject
  public Chocolate(final PeanutButter peanutButter) {
    super();
    this.peanutButter = peanutButter;
  }

}

The Dependency Injection Mindset

Now kindly forget CDI for a moment (and Spring if you’re coming from that background).

What is really important here is the mindset.

That mindset is: in any class you’re writing, take in only what you need to get your job done.  Pare it down more and more and more until you truly have the object you need.  Always be lazy; make your caller do the work of finding your dependencies!

Try if you can to pass them in in the constructor of your class and set them in private final instance fields.  Immutability is good!

The more you relentlessly and recursively pursue this mindset, the simpler your classes will be and the more clear the dependencies between them will be.

The fact that some of them might be “injected” by some kind of magic machine like CDI is utterly immaterial to your class design.  The dependency injection mindset is much more about the “dependency” part and much less about the “injection” part.

If there’s one thing you take away from this series of articles, let it be that programming using the dependency injection mindset—even if you never use a dependency injection framework like CDI (or Spring, or Jersey’s HK2)—is its own goodness.

Consumption

Within the dependency injection mindset, there are consumers and producers.

Consumers are like the Chocolate class above: they “take in” stuff, do their work, and are done.  A good consumer declares dependencies on exactly what it needs and doesn’t worry about how that stuff gets made or supplied or looked up or acquired.  In CDI, using @Inject at some location indicates that you’re doing consumer work there.

Consumption is the heart of the dependency injection mindset.

Production

Up to this point we’ve been focused on not worrying about where, for example, instances of PeanutButter come from or who makes them or how many little subassemblies go into ultimately manufacturing one.  All of these concerns are part of production.

For this article, a producer is something whose primary job is “handing out” an instance of something.  Sometimes “handing out” means “creating”, and sometimes it means acquiring or looking up.

Sometimes a producer “knows” it should hand out the same thing over and over again.  If you’ve programmed in Java for any length of time, you’ve run into someone somewhere who uses singletons and methods to hand them out.  These methods that return singletons are doing production work—they’re producers.

If you squint right, and look at things a certain way, another kind of producer that hands out the same thing over and over again is a field!  So looked at under the right lights, a field can be a producer.

Other times a producer “knows” it should hand out a new thing whenever called for.  Again, if you’ve been in the Java enterprise world for a while you’ve seen various Factory-suffixed classes.  Typically they have methods that start with create or make or get and they create or make something (often times a thing whose class is named the same thing as the factory class, minus the Factory suffix) and return it whenever they’re invoked.  These methods too are producers.

These kind of method-based producers obviously live “inside” classes (they’re methods, after all).  The things they make may or may not be instances of the classes the producers live inside.  For example, a PeanutButterFactory class may contain an acquirePeanutButter method that returns a PeanutButter instance.  Note that the class that houses the PeanutButter producer—PeanutButterFactory—in this case is not the same as the class of the return type of the method—PeanutButter.

Just so we can talk about things later let’s call the “housing” of a producer (whether it’s a field or a method) a producer class.  As we’ve seen above, in general—but with one notable exception described immediately below—the class of the thing being made (the field’s type, or the method’s return type) need not be the same as the producer class housing the producer (the field or the method) that makes the thing.

Finally, there are producers all over the place in plain sight that you may not think of.  They create new things every time when called for.  They’re called constructors!  Constructors have an interesting property, which is that they must be housed in the class that is the class of the instances they make.  So, for example, a PeanutButter constructor makes PeanutButter instances and can’t make anything else.

Another way to put this is that in the case of constructors, the producer class’ producer (the constructor) makes instances of the producer class itself.

So fields, methods and constructors are all producers if you look at them as sources of objects that someone might need.

Production and Consumption

Oftentimes, a method or constructor that is making or getting things to hand to a caller will need other raw materials to get the job done.  Maybe, as in our examples earlier, a producer of PeanutButter instances needs to get them from a GroceryStore.

Following the dependency injection mindset, there’s nothing to prevent a producer from also being a consumer!  That is, a method that for various business-related reasons returns or creates a PeanutButter instance from a GroceryStory shouldn’t look up a GroceryStore instance, or set about some other means of creating a GroceryStore, it should simply declare that it needs one.

Here’s what a PeanutButter-returning producer (method) might look like when it’s designed from within the dependency injection mindset.  Note that there’s no GroceryStore acquisition going on (no singletons, no LDAP, no database servers, no configuration subsystem):

public PeanutButter acquirePeanutButter(final GroceryStore store) {
  return store.get("Peanut butter");
}

Note that this method is a producer when we’re looking at it as a source of PeanutButter instances, and a consumer when we’re looking at it as something that needs a GroceryStore to do its job.

Wiring It Up

Suppose now we’ve written several classes using our dependency injection mindset.

So in our left hand we have consumers that need things to do their job.  In our right hand we have producers that make things should they ever be needed by someone (and may also consume things as part of that production process).

We can tell just by surveying the landscape that that method over there that returns PeanutButter instances—a PeanutButter producer—”goes with” this consumer over here, Chocolate, whose constructor needs PeanutButter instances.

Again, just by looking at things, we can see that if we wanted to ever instantiate a Chocolate for any reason, we’re first going to need a PeanutButter.

To get a PeanutButter, we’re going to have to call that PeanutButter-returning method.

To call that PeanutButter-returning method, we’re going to have to create an instance of the class it “lives” in, then…oops, we’re going to need a GroceryStore because—remember? see the examples above—the PeanutButter-returning method needs a GroceryStore to do its job.  So we’ll need to recursively go through this effort with GroceryStore—maybe it in turn is produced by a producer, or maybe we can just call its constructor.

This process of figuring out these relationships and instantiating the right things in the right order in order to come up with other things is known generically and colloquially as wiring.  You can do it by hand.  It’s not magic.

Wiring By Hand

For example, at the initialization of our program somewhere we could do something like this (this example deliberately has a few problems):

final GroceryStore groceryStore = new GroceryStore();
groceryStore.put("Peanut butter", new AdamsChunky());
final PeanutButterFactory factory = new PeanutButterFactory();
final PeanutButter peanutButter = factory.acquirePeanutButter(groceryStore);
final Chocolate c = new Chocolate(peanutButter);

This is an example of (deliberately slightly bad, but not awful) wiring by hand, but it shows wiring nonetheless.

We’ve made many choices here.  Some are obvious; some, when generalized into your enterprise project of choice beyond this stupid example—swap in your favorite system you love to hate in place of GroceryStore, for example—are perhaps not so easy to see:

  • We’ve chosen the kind of GroceryStore.
  • We’ve chosen the kind of PeanutButter.
  • We’ve explicitly said that our PeanutButter instance, regardless of what choice we made a line above, is going to come out of a GroceryStore.
  • We’ve also said that PeanutButter instances can be acquired from a factory method.  (Hmm; can that method be subclassed?  Are there now two “sources of truth” or more for PeanutButter instances?)
  • We’ve implied that PeanutButter instances are (effectively) singletons.  Maybe we didn’t mean to do this.  Maybe this matters; maybe not.

So we’ve deferred certain choices—a Chocolate takes in a PeanutButter, but isn’t choosy about what kind, or where it came from; a GroceryStore presumably allows you to put any kind of PeanutButter you like; we’ve abstracted the production of PeanutButter behind a black-box method (acquirePeanutButter)—which is nice.  But it is important to note that we’ve wired in many other hardcoded choices above.

Many enterprise projects will have something like this, and a well-meaning developer will say, ah, hardcoding is bad; let’s allow someone to configure the kind of PeanutButter to use so it isn’t always AdamsChunky.  So they introduce a configuration file or mechanism that looks up the kind of PeanutButter to use—and now we’re out of the dependency injection mindset.  Oops!

That is: there will now be code in this initialization sequence that requires a certain configuration mechanism to look up the precise type of PeanutButter required.  Then someone will come along and try to abstract that configuration mechanism.  These are instances of slightly buried service locator patterns applied intentionally and unintentionally in the initialization code—and then suddenly it turns out that for reasons no one is entirely sure of you have to have an LDAP server or database running in order to test a Chocolate instance.  Ugh!  What happened to our “just declare the thing you need”?

And where does CDI come in?

Automatic Wiring

CDI is that well-meaning developer, and the author of the initialization code above, but way better: it does the wiring correctly, automatically and well without interfering with the dependency injection mindset.  As you can probably see by now, that initialization code is the process of matching producers with consumers, and that is exactly what (this area of) CDI does.  It has been doing this work correctly and well for many, many years.

Armed with this foundation (the dependency injection mindset, seeing the world in terms of producers and consumers and a middle-player that wires them together properly and efficiently), we can move on in the next post to how CDI does this.