Ronaldo Lanhellas
Ronaldo Lanhellas

Reputation: 3336

Creating a normal class with injections from Spring

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

Answers (2)

aim
aim

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

Emil Sit
Emil Sit

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

Related Questions