Home CDI Dependency Injection @PostConstruct and @PreDestroy Example
Post
Cancel

CDI Dependency Injection @PostConstruct and @PreDestroy Example

We have seen how to inject cdi beans by using qualifiers and producers so far. Additionally, every cdi bean has a lifecycle, and we can initialize and prepare to destroy any managed bean by using two common annotations; @PostConstruct and @PreDestroy. Methods annotated with these annotations are called bean lifecycle callbacks.

@PostConstruct

Due to the Weld Reference injection and initialization happens in this order;

  • First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to obtain an instance of the bean.
  • Next, the container initializes the values of all injected fields of the bean.
  • Next, the container calls all initializer methods of bean (the call order is not portable, don’t rely on it).
  • Finally, the @PostConstruct method, if any, is called.

So, the purpose of using @PostConstruct is clear; it gives you a chance to initialize injected beans, resources etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Person {

    // you may have injected beans, resources etc.

    public Person() {
        System.out.println("Constructor is called...");
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct is called...");
    }
}

So, the output by injecting a Person bean will be;

1
2
Constructor is called...
@PostConstruct is called...

One important point about @PostConstruct is, it won’t be invoked if you try to inject and initialize bean through producer methods. Because using a producer method means that you are programmatically creating, initializing, and injecting your bean with new keyword.

@PreDestroy

The second lifecycle call back method for a bean is annotated with @PreDestroy. It prepares the managed bean to get destroyed. It is used for cleaning up operations, or releasing any resources. Finally, the method annotated with @PreDestroy is called by CDI container when the life cycle of bean is finished.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Person {

    // you may have injected beans, resources etc.

    public Person() {
        System.out.println("Constructor is called...");
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct is called...");
    }

    @PreDestroy
    public void dispose() {
        System.out.println("@PreDestroy is called...");
    }
}

We can see a very simple example about the life cycle a Person bean in a test method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RunWith(Arquillian.class)
public class PersonTest {

    @Deployment
    public static WebArchive createJavaTestArchive() {
        return ShrinkWrap.create(WebArchive.class)
                .addPackage("predestroy_and_postconstruct")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Inject
    private Person person;

    @Test
    public void test() {
        System.out.println("running test");
    }
}

Output;

1
2
3
4
Constructor is called...
@PostConstruct is called...
running test
@PreDestroy is called...

Again like producer methods, if we try to destroy a bean with a disposer method then method annotated with @PreDestroy won’t be invoked due to the same reason which applies for producer methods.

This post is licensed under CC BY 4.0 by the author.

Java Enums Tutorial

Spring Retry Tutorial

Comments powered by Disqus.