Why is constructor of CDI bean class called more than once
Asked Answered
S

2

6

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.

Stevie answered 22/8, 2013 at 11:1 Comment(3)
Just blind guessing but try to use @PostConstruct method to see if it gets called twice.Rhonda
@@PostConstruct is called only once, which is exactly what I need. With this hint I also found a related question [why-use-postconstruct]. If you post this as answer I will accept it. Thanks, @Adrian.Stevie
You should use interfaces to instead of concrete classes to inject.Crosslet
S
11

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?

Stevie answered 26/8, 2013 at 9:40 Comment(0)
F
0

That is a javassist proxy object created for your singleton. The singleton contructor should just be called when the actual object is created.

Faviolafavonian answered 22/8, 2013 at 17:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.