Creating a Custom CDI Scope

This post is based on my learnings while creating SimpleBPM and will cover the creation of a simple custom scope. The built-in scopes (Application, Session, Conversation etc) are all you really need most of the time but there may be times when you want more control or need to do some other custom actions. The best example I have for this is when a business process is running. I wanted a scope that exists possibly through many requests, different pages, and possibly multiple conversations. You can think of this scope as longer lived than a conversation but shorter than session scoped.

There are a few things we need to create and activate our custom CDI scope so I’ll go over each one below.

 

First up we need to create an annotation to represent our new scope.

Next, we can create our extension which is responsible for registering our new custom scope.

Above we can see that we need to add our new annotation in the beforeBeanDiscovery phase using an even listener. We also need to register a class which implements the Context. The code for this is shown below.

This is the main class and is basically a factory for creating and retrieving beans from your scope. The get methods are called by CDI when trying to resolve beans in your scope. In my example, above I can use this to hook into the JBPM WorkflowProcessInstance to get and set process variables.

Finally, we can activate our new extension and scope by placing the fully qualified name of our extension class in a special file called javax.enterprise.inject.spi.Extension which is placed /src/main/resources/services

You can then use your scope by annotating beans with your scope annotation as you would normally for any of the built-in scopes.