<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mauro Codella</title>
    <description>The latest articles on DEV Community by Mauro Codella (@codespair).</description>
    <link>https://dev.to/codespair</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2989112%2F690bf936-b599-4b7c-9dc7-17d6d65618a7.png</url>
      <title>DEV Community: Mauro Codella</title>
      <link>https://dev.to/codespair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codespair"/>
    <language>en</language>
    <item>
      <title>A Practical Introduction to CDI and Weld SE // The Basics</title>
      <dc:creator>Mauro Codella</dc:creator>
      <pubDate>Sat, 29 Mar 2025 20:26:30 +0000</pubDate>
      <link>https://dev.to/codespair/weld-cdi-for-the-impatient-3bnc</link>
      <guid>https://dev.to/codespair/weld-cdi-for-the-impatient-3bnc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of the ways to ensure that applications do not become overly complex as they grow is to maintain loosely coupled components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cdi-spec.org/" rel="noopener noreferrer"&gt;Jakarta EE CDI&lt;/a&gt; is a specification that, quoting directly, "&lt;em&gt;defines a powerful set of complementary services that help improve the structure of application code&lt;/em&gt;". CDI stands for &lt;strong&gt;&lt;em&gt;Context and Dependency Injection&lt;/em&gt;&lt;/strong&gt; and &lt;a href="https://weld.cdi-spec.org/" rel="noopener noreferrer"&gt;Weld&lt;/a&gt; is its reference implementation.&lt;/p&gt;

&lt;p&gt;CDI enables us to write loosely coupled code, and in this post we will see how we can leverage Weld for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loose coupling and &lt;code&gt;@Inject&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most common forms of coupling is the knowledge that one component has about how to instantiate another component, as shown in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Knowing how to instantiate B increases A's coupling to B.&lt;/span&gt;
    &lt;span class="no"&gt;B&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="o"&gt;(...);&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using Weld, the previous code would be modified as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Weld will instantiate A and inject it with an instance of B&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;A&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;B&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The easiest way to get started with Weld is by using &lt;a href="https://docs.jboss.org/weld/reference/latest/en-US/html_single/#weld-se" rel="noopener noreferrer"&gt;Weld SE&lt;/a&gt;, which allows you to explore Weld in a standard Java SE application. The simplest approach is to use the &lt;a href="https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se-shaded" rel="noopener noreferrer"&gt;weld-se-shaded&lt;/a&gt; artifact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.jboss.weld.se&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;weld-se-shaded&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;6.0.2.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Weld SE on the classpath, let's assume we have a class named Bean and that we want to delegate the responsibility of instantiating it to Weld.&lt;/p&gt;

&lt;p&gt;What we need to do is build a &lt;strong&gt;&lt;em&gt;container&lt;/em&gt;&lt;/strong&gt; by adding Bean as a &lt;strong&gt;&lt;em&gt;bean class&lt;/em&gt;&lt;/strong&gt;—and then initialize the container.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;container&lt;/em&gt;&lt;/strong&gt; is essentially what instantiates &lt;strong&gt;&lt;em&gt;beans&lt;/em&gt;&lt;/strong&gt;, satisfies their dependencies and manages their lifecycle.&lt;/p&gt;

&lt;p&gt;Disabling &lt;strong&gt;&lt;em&gt;auto discovery&lt;/em&gt;&lt;/strong&gt; means, in broad terms, that we prefer to programmatically build and initialize the &lt;strong&gt;&lt;em&gt;container&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.jboss.weld.environment.se.Weld&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.jboss.weld.environment.se.WeldContainer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;WeldContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Weld&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// We will provide everything programmatically&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disableDiscovery&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// We add Bean to the container so that it can&lt;/span&gt;
        &lt;span class="c1"&gt;// instantiate it for us&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBeanClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// We ask the container to provide us with an instance&lt;/span&gt;
    &lt;span class="c1"&gt;// of Bean so that we can utilize it&lt;/span&gt;
    &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="n"&gt;bean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bean has performed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;Main.main()&lt;/code&gt; will print "&lt;em&gt;Bean has performed&lt;/em&gt;" to the console.&lt;/p&gt;

&lt;p&gt;As depicted in the image below, &lt;code&gt;container.select(Bean.class).get()&lt;/code&gt; will return an instance of &lt;code&gt;Bean&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1logbd46axsduahcut2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1logbd46axsduahcut2.png" alt="Image depicting the container providing an instance of Bean" width="390" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's make things more interesting by having the Bean class depend on another class: &lt;code&gt;TransitiveBean&lt;/code&gt;. We want to leverage Weld to instantiate &lt;code&gt;TransitiveBean&lt;/code&gt; for us and then pass the obtained instance to Bean. To achieve this, we can add &lt;code&gt;TransitiveBean&lt;/code&gt; to the Weld container, restructure Bean to receive an instance of &lt;code&gt;TransitiveBean&lt;/code&gt; via its constructor, and annotate the constructor with &lt;code&gt;@jakarta.inject.Inject&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;WeldContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Weld&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disableDiscovery&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// Adding the beans to the container so that we can&lt;/span&gt;
        &lt;span class="c1"&gt;// delegate their instantiation to it.&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBeanClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransitiveBean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBeanClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="n"&gt;bean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;TransitiveBean&lt;/span&gt; &lt;span class="n"&gt;transitiveBean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransitiveBean&lt;/span&gt; &lt;span class="n"&gt;transitiveBean&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// The container will first create an instance of&lt;/span&gt;
      &lt;span class="c1"&gt;// TransitiveBean, and then pass (inject) it as&lt;/span&gt;
      &lt;span class="c1"&gt;// an argument to this constructor&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;transitiveBean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transitiveBean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;transitiveBean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;transitivePerform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TransitiveBean&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;transitivePerform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TransitiveBean has performed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that a bean may annotate at most one of its constructors with @Inject.&lt;/p&gt;

&lt;p&gt;This time, running &lt;code&gt;Main.main()&lt;/code&gt; will print &lt;strong&gt;&lt;em&gt;TransitiveBean has performed&lt;/em&gt;&lt;/strong&gt;. The container relieved Bean from being more tightly coupled to &lt;code&gt;TransitiveBean&lt;/code&gt; than necessary. The following picture depicts what the container did for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8puuuq24d8mn3zmd68k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8puuuq24d8mn3zmd68k.png" alt="Image depicting the container providing an instance of Bean and satisfying its dependency on TransitiveBean" width="531" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The container is pretty flexible when it comes to finding a way to satisfy an injection point. If &lt;code&gt;TransitiveBean&lt;/code&gt; were to implement an interface—say, &lt;code&gt;TransitiveInterface&lt;/code&gt;—then &lt;code&gt;Bean&lt;/code&gt; could safely replace its constructor parameter type &lt;code&gt;TransitiveBean&lt;/code&gt; with &lt;code&gt;TransitiveInterface&lt;/code&gt;, and the container would still be able to satisfy it. If we don't intend &lt;code&gt;TransitiveBean&lt;/code&gt; to satisfy injection points typed with &lt;code&gt;TransitiveInterface&lt;/code&gt;, we can restrict the types it can satisfy by annotating it with &lt;code&gt;@Typed&lt;/code&gt;. More on this can be found in the CDI rpecification: &lt;a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#restricting_bean_types" rel="noopener noreferrer"&gt;Restricting the bean types of a bean&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Injection can also occur via two more mechanisms. It can be done via &lt;strong&gt;&lt;em&gt;initializer methods&lt;/em&gt;&lt;/strong&gt;—such as a setter method—or via &lt;strong&gt;&lt;em&gt;field injection&lt;/em&gt;&lt;/strong&gt;—directly on the fields. More on injection can be found in the Weld specification—&lt;a href="https://docs.jboss.org/weld/reference/latest/en-US/html_single/#_injection_points" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Injection points&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In real-world applications, the container will be utilized to manage many more beans, with more complicated dependency relationships. In the following sections, we'll explore other ways to declare beans, their scope, and the lifecycle of a bean instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scopes
&lt;/h2&gt;

&lt;p&gt;In simple terms, the &lt;strong&gt;&lt;em&gt;scope&lt;/em&gt;&lt;/strong&gt; of a bean determines the lifecycle of its instances. It tells the container whether to create a distinct instance for each injection point that resolves to a given bean type, or to inject a single shared instance instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@ApplicationScoped&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A bean annotated with &lt;code&gt;@jakarta.enterprise.context.ApplicationScoped&lt;/code&gt; is instantiated only once by the container, and that single instance is used to satisfy all applicable injection points. &lt;code&gt;@ApplicationScoped&lt;/code&gt; is considered a &lt;strong&gt;&lt;em&gt;normal scope&lt;/em&gt;&lt;/strong&gt; by the Weld specification, meaning that a proxy to the actual bean instance—also known as a &lt;strong&gt;&lt;em&gt;client proxy&lt;/em&gt;&lt;/strong&gt;—is what's injected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q6s62wo0gk06s9dwmxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q6s62wo0gk06s9dwmxy.png" alt="Image depicting the behavior of the @ApplicationScoped annotation" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Why a client proxy?
&lt;/h4&gt;

&lt;p&gt;Using client proxies comes with a set of advantages. Paraphrasing from the &lt;a href="https://weld.cdi-spec.org/documentation/#13" rel="noopener noreferrer"&gt;Weld documentation&lt;/a&gt;, these include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Serialization&lt;/em&gt;&lt;/strong&gt; — Client proxies are serializable, even if the actual bean instance is not. This can be useful in certain scenarios, as explained in more detail in the Weld reference documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Lazy Creation&lt;/em&gt;&lt;/strong&gt; — The proxied bean instance isn't created until it's actually needed. This behavior can improve performance, as discussed in Weld Tip 3 - Boost performance of Weld apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Circular Dependencies&lt;/em&gt;&lt;/strong&gt; — Client proxies make it possible to handle circular dependencies, which would otherwise be problematic in dependency injection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Manual Bean Destruction&lt;/em&gt;&lt;/strong&gt; — Since the injected object is a proxy, the actual bean instance can be safely swapped or destroyed manually when needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That said, client proxies can sometimes interfere with the expected behavior of an application. This might happen when a bean cannot be proxied—such as when it's a final class—or when its fields are meant to be accessed directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@Singleton&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Just like with &lt;code&gt;@ApplicationScoped&lt;/code&gt;, a bean annotated with &lt;code&gt;@jakarta.inject.Singleton&lt;/code&gt; is also instantiated only once. However, unlike &lt;code&gt;@ApplicationScoped&lt;/code&gt;, it is injected directly—without using a client proxy, as illustrated in the figure below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2sjlh34i53zqa63uqlo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2sjlh34i53zqa63uqlo.png" alt="Image depicting the behavior of the @Singleton annotation" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This lack of a client proxy is what makes &lt;code&gt;@Singleton&lt;/code&gt; a &lt;strong&gt;&lt;em&gt;pseudo-scope&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@Dependent&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If a bean is not annotated, or is annotated with &lt;code&gt;@jakarta.enterprise.context.Dependent&lt;/code&gt;, the container will create a distinct instance for each injection point that needs to be satisfied. Just like &lt;code&gt;@Singleton&lt;/code&gt;, &lt;code&gt;@Dependent&lt;/code&gt; is a pseudo-scope, and bean instances are injected directly—without the use of a client proxy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xpujts87wbq53fidfos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xpujts87wbq53fidfos.png" alt="Image depicting the behavior of the @Dependent annotation" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@Dependent&lt;/code&gt; bean instances are created when the injected bean is created, and destroyed when the injected bean is destroyed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further reading
&lt;/h3&gt;

&lt;p&gt;More about scopes can be found in the CDI specs: &lt;a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#scopes" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Scopes&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Producer methods
&lt;/h2&gt;

&lt;p&gt;Bean classes aren’t the only way the container can create injectable instances—&lt;strong&gt;&lt;em&gt;producer methods&lt;/em&gt;&lt;/strong&gt; can also be utilized. A producer method is created by annotating a bean method with &lt;code&gt;@jakarta.enterprise.inject.Produces&lt;/code&gt;. The container will invoke a producer method when it needs an instance of the same type as the one returned by the method.&lt;/p&gt;

&lt;p&gt;Producer methods offer some flexibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The produced objects don’t need to be actual bean instances.
&lt;/li&gt;
&lt;li&gt;The specific type of the produced object can be determined at runtime.
&lt;/li&gt;
&lt;li&gt;You can produce and inject instances of types from third-party libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following snippet shows how to make the Weld container aware of methods annotated with &lt;code&gt;@Produces&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;WeldContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Weld&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disableDiscovery&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBeanClasses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BeanWithProducers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;External&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BeanWithProducers&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Produces&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="nf"&gt;produceExternal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;External&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"External has performed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;Main.main()&lt;/code&gt; will print &lt;strong&gt;&lt;em&gt;External has performed&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Producer methods are treated as initializer methods, which means that if they have parameters, the container will try to satisfy them when invoking the method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nd"&gt;@Produces&lt;/span&gt;
    &lt;span class="c1"&gt;// When this method is invoked, the container will pass an instance&lt;/span&gt;
    &lt;span class="c1"&gt;// of AnotherBean as an argument.&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="nf"&gt;produceExternal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AnotherBean&lt;/span&gt; &lt;span class="n"&gt;anotherBean&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;External&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anotherBean&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scope of a producer method is not inherited from the bean it's defined in. Just like with bean classes, the default scope for a producer method is &lt;code&gt;@Dependent&lt;/code&gt;, and it's possible to explicitly use other scopes, such as &lt;code&gt;@ApplicationScoped&lt;/code&gt; and &lt;code&gt;@Singleton&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disposer methods
&lt;/h3&gt;

&lt;p&gt;Along with producer methods, it's possible to specify &lt;strong&gt;&lt;em&gt;disposer methods&lt;/em&gt;&lt;/strong&gt;. A disposer method is defined in a bean class and has one of its parameters annotated with &lt;code&gt;@jakarta.enterprise.inject.Disposes&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="nd"&gt;@Produces&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="nf"&gt;produceExternal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;External&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;disposeExternal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Disposes&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="o"&gt;[...]&lt;/span&gt; 

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;External&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"External has performed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dispose&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"External has been disposed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an instance of the same type as the one annotated with &lt;code&gt;@Disposes&lt;/code&gt; needs to be destroyed, the disposer method will be invoked.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;Main.main()&lt;/code&gt; will print &lt;strong&gt;&lt;em&gt;External has performed&lt;/em&gt;&lt;/strong&gt;, followed by &lt;strong&gt;_External has been disposed&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further reading
&lt;/h3&gt;

&lt;p&gt;More on producer methods can be found in the Weld reference—&lt;a href="https://docs.jboss.org/weld/reference/latest/en-US/html_single/#producer_methods" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Producer methods&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifecycle callbacks
&lt;/h2&gt;

&lt;p&gt;Bean instances are created and eventually destroyed according to the scope they are given. It's possible to intercept these lifecycle events and invoke methods accordingly. CDI provides the &lt;code&gt;@jakarta.annotation.PostConstruct&lt;/code&gt; and &lt;code&gt;@jakarta.annotation.PreDestroy&lt;/code&gt; annotations, which can be used on methods of a bean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;WeldContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Weld&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disableDiscovery&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBeanClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="n"&gt;bean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;bean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bean&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bean has performed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostConstruct&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;postConstruct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postConstruct() invoked"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PreDestroy&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;preDestroy&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"preDestroy() invoked"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;Main.main()&lt;/code&gt; will print the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postConstruct() invoked
Bean has performed
preDestroy() invoked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;@PostConstruct&lt;/code&gt; methods are called after all injection has been performed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What now?
&lt;/h2&gt;

&lt;p&gt;Covering Weld SE is a large task—this post alone probably just scratches the surface of all the capabilities it has to offer. If you want to delve deeper into the topics introduced here—or explore more advanced concepts—check out the &lt;a href="https://docs.jboss.org/weld/reference/latest/en-US/html_single/" rel="noopener noreferrer"&gt;Weld reference&lt;/a&gt; and the &lt;a href="https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html" rel="noopener noreferrer"&gt;CDI specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You might also be interested in checking out my &lt;a href="https://github.com/codella/weld-playground" rel="noopener noreferrer"&gt;Weld playground&lt;/a&gt;, which I created to support many of the examples featured in this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy welding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>weld</category>
      <category>cdi</category>
      <category>java</category>
      <category>jakarta</category>
    </item>
  </channel>
</rss>
