0

I'm trying to use Spring and Jhipster to access some Database. I want to use a service, using injection.

When using a rest Controller, I have no problem, but when I'm trying to use an injected service in a pojo, this service is null.

@RestController
public class TheRestController {

    @Autowired
    protected TheService theService;

    @RequestMapping("/test")
    public void test() {

        if (theService == null) {
            System.out.println("rest : null");
        }
        {
            System.out.println("Rest : service is not null");
        }

        System.out.println("Call Pojo ");

        Pojo pojo = new Pojo();
        pojo.process();
    }
}

The service is not null and could be used to acces to the database. But when I try to use the Pojo, in the rest controller or directly in the main(), the Service is null.

My Pojo is exactly the same as the Rest controller :

public class Pojo  {

    @Autowired
    protected TheService theService;     // this one is allways null.

    public void process(){
        if (theService == null){
            System.out.println( "POJO : null" );
        }else{
            System.out.println("POJO : service is not null");
        }
    }
}

When sending a request, I have the output :

Rest : service is not null
Call Pojo 
POJO : null

I tried with @Autowired, @Resource and @Inject, same result.

how can I access to theService in a Pojo (without allways passing it as an a parameter) ?

GaspardP
  • 880
  • 1
  • 12
  • 24

2 Answers2

2

Spring container can only manage beans (objects) created within that container - if you create an object using new keyword, Spring has no way to inject the dependencies (it doesn't even know that the object exists). If you want to use dependencies in main(), you have to:

  • Declare the Pojo in the Spring configuration, or annotate it as @Component or @Service

  • Create a new Spring container in your main:

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register("path.to.your.package");
    context.refresh();
    
  • Get the (Spring-managed) instance of Pojo:

    Pojo myPojo = context.getBean(Pojo.class);
    
Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • Great ! I was close to understand Spring and dependency injection, and it seems that your answer help me a lot. I should defined all component as "Component", then I shall not build them using "new" but as field, using Inject. Bonus question : shall I use Inject or Autowired ? or it does not matter ? – GaspardP Oct 12 '15 at 15:05
  • @GaspardP see http://stackoverflow.com/questions/7142622/what-is-the-difference-between-inject-and-autowired-in-spring-framework-which – Jiri Tousek Oct 12 '15 at 15:09
0

I'll just add to Jiri's answer (which I don't recommend unless Pojo is a singleton).

You should be aware of lifecycles. If Pojo is not a singleton I don't recommend you use Spring to manage instances of Pojo or autowire or both (although it can be done it is slow and there is a difference between just autowiring and managing).

That is if your creating Pojo per request you should NOT use Spring to manage the wiring and creation of the object.

For general edification you can have beans automagically wired via normal object construction ie new Pojo through AspectJ and @Configurable. These beans are autowired by spring but not managed by spring.

Spring also supports managing and autowiring non-singleton beans (see Spring scope) but I really do not recommend doing that.

Instead you should create singletons (spring managed component ie @Service or @Component) for creating non-singleton objects like Pojo. This is called the Factory pattern.

Adam Gent
  • 47,843
  • 23
  • 153
  • 203