CDI Part 4 - Lazy Initialization

Part 4 - CDI Lazy Initialization

Hello!

This is the Part 4 of the CDI Series in Java that contains:

  • Part 1: Factory in CDI with @Produces annotation
  • Part 2: CDI Qualifiers
  • Part 3: Events and Observers in CDI
  • Part 4: CDI and Lazy Initialization
  • Part 5: Interceptors in CDI
  • Part 6: CDI Dependency Injection and Alternatives
  • Part 7: Working with CDI Decorators

In the today's post we're going to see Lazy Initialization using CDI!

Let's contextualize our application problem.

  • We must have a Checkout class
  • We must send an Email when a checkout is finished
  • We must create a Metric when a checkout is finished

But wait! We just can send an email if the user is not optIn, right? We wouldn't like to spam him!

Step 1 - Creating the Entire Scenario

The first class will use CDI 2.0 in the standalone mode just to keep things simple. With CDI 2.0 we can use CDI in standalone environment, but you can use Lazy Initialization since the CDI 1.0

The following class creates the CDI Container that allows us to use Dependency Injection:

Ok. We don't have the User class, so let's create it:

It's time to create the Checkout class:

Last, let's create the EmailSender and MetricCreator classses:

Awesome! Pretty simple so far. Let's run the method main():

As you can see, everything is up and running as we expected, right?

Wait! We forgot to test if the user is an OptIn user, otherwise we'll' send emails that can go directly to the spam box

Fixing it..

Cool! Let's run it again:

Without any news here.

But if we change the OptIn from user?

As you can notice, the User is no longer an OptIn.

That's ok, let's run the method main() again:

As you can see in the message that has been printed, we are not sending email to the User anymore.

But wait! Did you see all the log? Notice:

Hey, but the user is not an OpInt and I will not send an email to him! So, probably, I don't need to construct the EmailSender, right?

Yes, CDI will Inject your dependencies, even if you not use them!

When CDI needs to Inject the Checkout class, CDI will:

  • Hmm, I need to create an instance of Checkout class for you
  • But Checkout class has a dependency to EmailSender class. I'll inject it and I don't care if you will or will not use it
  • But the Checkout class has a dependency to MetricCreator class. Again, I'll inject it for you and I don't care if you will or will not use it

And that's it! But sometimes the class being injected is:

  • Heavy to be created
  • Has another dependencies (that will be inject by CDI) and it could be really expensive
  • Or we just don't know if it will be used

What do you think about Inject that just when you need it?

Step 2 - CDI Lazy Injection

CDI has an important interface called Instance. This interface allows the application to dynamically obtain instances that may or may not have qualifiers.

To use this interface, you can ask yourself a few questions?

  • The bean type vary dynamically at runtime?
  • The bean type needs to be injected based on Qualifiers at runtime?
  • Do you need to iterate through all beans to pick up which you are interested in?

After you ask these few questions, you may use the Instance interface to Inject the bean dynamically

So, that's our case! Let's use the Instance interface to inject the EmailSender object just if the user is OptIn

In the code above, notice that we can't just call emailSender.sendEmailFor(user) since the type of the Injected point is Instance and not EmailSender.

To retrieve the instance and take the object injected, we must use the .get() method from the Instance interface.

If we run our code again, we will have the following result:

Great! Our user is not OptIn and the EmailSender class was not created. It will be created just if the user is OptIn \o/

Step 3 - Lazy Initialization in a Bad Code Design

Imagine the following code:

Besides the terrible example, this code can have a bad code design. Notice that the Stock object is used by just 1 method in 4.

Again, even if you're calling the finishThirdLogic() method, the Stock object will be injected by CDI.

In this situation, you could use Lazy Initialization to inject the Stock object just in the desired method:

That's it! Lazy Initialization with CDI.

Would you like to get the complete code? Just get it from GitHub repository! You can try yourself \o/

I hope that this post can be helpful to you! Have any question or suggestion? Please, feel free to write a comment below.

It's time to jump into the next part: Part 5: Interceptors in CDI

Thanks!

Alexandre Gama

Alexandre Gama

Hacking Code Founder

Hacking Code Founder and Writer, Passionate Senior Software Engineer and Team Leader at @Elo7, Teacher of several courses at Caelum, Speaker at many conferences and terrible guitar player.
CDI - Factories with @Produces Annotation - Hacking Code Java Tutorial

CDI - Factories with @Produces Annotation

Do you want to create powerful and easy Factories in CDI? Let's see how!

CDI Qualifiers Tutorial - Java CDI Guide by Hacking Code

CDI Qualifiers

Working with CDI Qualifiers
CDI Observers and Events Tutorial - Java CDI Guide by Live Coding

CDI Events and Observers

Let's see why and how to use CDI Events and Observers
CDI Lazy Initialization Tutorial - Java CDI Guide by Live Coding

CDI Lazy Initialization Tutorial

Did you know that we can initialize CDI beans lazily?
CDI Interceptors Tutorial - Java CDI Guide by Live Coding

CDI Interceptors

How to use CDI Interceptors from scratch
CDI Alternatives Tutorial - Java CDI Guide by Live Coding

CDI Alternatives Tutorial

Lear how to use Argument Matcher in its Fundamental way

CDI Decorator Tutorial - Java CDI Guide by Live Coding

CDI Decorator Tutorial

CDI Decorator is a powerful feature to deal with business Decoration!

0 Comments

Trackbacks/Pingbacks

  1. CDI – Decorators | Hacking Code - […] 5 […]
  2. CDI – Creating Factories with @Produces Annotation | Hacking Code - […] Part 4: CDI and Lazy Initialization […]

Leave a Reply

Share This
Subscribe To Our Newsletter

Subscribe To Our Newsletter

Join our mailing list to receive the latest news and updates from our team.

You have Successfully Subscribed!

%d bloggers like this: