Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is constructor of CDI bean class called more than once

I have annotated a class with @ApplicationScoped. With @Inject I get instances of this class injected into several @RequestScopded JAX-RS services:

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
}

@RequestScoped
public class MyRS {
  @Inject MySingleton mySingleton;
  public void someMethod() {
    // do something with mySingleton
  }
}

Basically this works fine. Howeger, at least when I run this in WebSphere 8.5 the constructor of MySingleton is invoked twice, resulting in output like

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.

I planned to do some expensive initialization in the constructor, which would obviously be executed twice.

I believe that one of the constructor calls is for generating some kind of proxy for the actual "worker" instance. But how can I avoid having my initialization code executed twice? The "solution" to do a lazy initialization in all methods of MySingleton is not very attractive.

like image 482
Gerhard Avatar asked Aug 22 '13 11:08

Gerhard


1 Answers

The constructor of managed beans may be called by the container also for creating proxies. For any "real" initialization Java EE therefore provides the annotation @PostConstruct. In an @ApplicationScoped bean a method annotated with @PostConstruct is called exactly once by the container:

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
  @PostConstruct
  init() {
    System.out(this + " initd.");
  }
}

Output:

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.
my.package.MySingleton@e51e26d1 initd.

Related question: Why use @PostConstruct?

like image 146
Gerhard Avatar answered Oct 03 '22 06:10

Gerhard