I'm trying to inject a logger object in a class that is implemented following a singleton approach.
The code almost looks like this:
Logger
class:
public class LoggerFactory {
@Produces
public Logger getLogger(InjectionPoint caller){
return Logger.getLogger(caller.getMember().getDeclaringClass().getName());
}
}
Then I create a class that needs logger and implements the Singleton Pattern:
public class MySingleton{
@Inject
private Logger logger;
private MySingleton instance;
/*
* Private constructor for singleton implementation
*/
private MySingleton(){
logger.info("Creating one and only one instance here!");
}
public MySingleton getInstance(){
if(instance == null) {
instance = new MySingleton();
}
return instance;
}
}
If I run the code (on Glassfish 3.1.2.2) I get a NPE as soon as I try to use the logger.
What I'm doing wrong (beans.xml
file is in place)?
I've also tried using @Inject
with a setter method for the Logger
object but with no luck.
Injections happens after construct. So you cant use it in the constructor.
One way is to add a method annotated @PostConstruct that can will be invoked after injections.
@PostConstruct
public void init() {
logger.info("Creating one and only one instance here!");
}
On a sidenote i Think you are aprouching the problem in the wrong way. CDI has a nice singleton support
create a class annotated @Singleton
@Singleton
public class MySingleton {
@Inject
Logger logger;
@PostConstruct
public void init() {
logger.info("Creating one and only one instance here!");
}
}
Above assumes you are using CDI for java ee (JSR-299).
If you are using JSR 330 Dependency Injection (guice etc.) link
You could use constructor injection:
@Singleton
public class MySingleton {
private final Logger logger;
@Inject
public MySingleton (Logger logger) {
this.logger = logger;
logger.info("Creating one and only one instance here!");
}
}