5

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Gerhard
  • 285
  • 3
  • 12
  • Just blind guessing but try to use @PostConstruct method to see if it gets called twice. – Adrian Mitev Aug 22 '13 at 13:15
  • @@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. – Gerhard Aug 22 '13 at 14:42
  • You should use interfaces to instead of concrete classes to inject. – Sazzadur Rahaman Aug 24 '13 at 13:31

2 Answers2

10

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?

Community
  • 1
  • 1
Gerhard
  • 285
  • 3
  • 12
0

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

Robert Höglund
  • 954
  • 9
  • 12