Reputation: 3336
Well, I have a normal class (LovHelper) that is responsible for doing some utils tasks. When i say normal class is because LovHelper.java don't have @Component, @Service or @Repository annotation.
Inside of this "normal class" i wanna inject a bean from spring, but the bean is always null. Look my Class LovHelper.java bellow:
package br.com.odontonew.helper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import br.com.odontonew.bean.Lov;
import br.com.odontonew.dao.BasicDAO;
public class LovHelper {
@Autowired
private BasicDAO dao;
private static LovHelper instance;
private LovHelper(){
}
public static LovHelper getInstance(){
if (instance == null)
instance = new LovHelper();
return instance;
}
public Lov getLovByCodigo(Class lovClass, String codigo){
Map<String,Object> map = new HashMap<String,Object>();
map.put("codigo", codigo);
List<Lov> lovs = (List<Lov>)dao.findByQuery("SELECT c FROM "+lovClass.getName()+" c WHERE c.codigo = :codigo", map);
if (lovs.size() == 1)
return lovs.get(0);
else
return null;
}
/*Getters and Setters*/
public BasicDAO getDao() {
return dao;
}
public void setDao(BasicDAO dao) {
this.dao = dao;
}
}
So, in another class i just call: LovHelper.getInstance().getLovByCodigo(param1, param2). But i always get a NullPointerException because the bean "dao" within LovHelper is NULL.
After think a little i decided to change my LovHelper.java (using singleton pattern) to a Bean for Spring inject, then I put @Component annotation and remove all singleton pattern the was developed. And in another class i inject "lovHelper" and use like this: lovHelper.getLovByCodigo(param1, param2). This second solution works fine, but the first not.
Finally, my doubt is: Why the original code (as posted) don't works.
Upvotes: 2
Views: 5605
Reputation: 1493
Your helper should be context aware, but you can make it static:
@Component
public class LovHelper {
private static LovHelper instance;
@PostConstruct
void init() {
instance = this;
}
// do stuff
In this case static instance will keep reference to Spring aware bean.
Upvotes: 0
Reputation: 23542
Spring will only handle injection dependencies to a class that is constructed by the container. When you call getInstance()
, you are allocating the object itself... there is no opportunity there for Spring to inject the dependencies that you have @Autowired
.
Your second solution works because Spring is aware of your LovHelper
class; it handles constructing it and injecting it into your other class.
If you don't want to mark the class with@Component
, you can declare the class as a bean directly in your XML configuration. If you don't want to have it be a singleton, you can set it with prototype scope.
If you really need to manage the class yourself, you could consider looking at @Configurable
. I believe it is intended to solve this problem but it requires aspects and I have not played with it myself.
Upvotes: 5