Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use autowired (@Autowired) references from main(String[] args) method?

I am trying to use an autowired reference from main class and am facing :

Cannot make a static reference to the non-static field zipCodeLookupService.

This is obvious. But I want to know how to handle this situation. What is the correct way of autowiring when main class is involved. My code will be as below -

Interface class

package com.example.services;
public interface IZipCodeLookup {
    String retriveCityForZip(String zipCode);
}

Service Class

package com.example.services;

import org.springframework.stereotype.Service;

@Service
public class ZipCodeLookupService implements IZipCodeLookup {

    @Override
    public String retriveCityForZip(String zipCode) {

        //below is mock code. actual code does a db lookup using a DAO.
        if(zipCode=="94123") return "San Francisco";
        return "not found in DB";
    }
}

here is the main class that requires the service class

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.example.services.IZipCodeLookup;

@SpringBootApplication
public class AutowireWithMainClassApplication {

    @Autowired
    IZipCodeLookup zipCodeLookupService;

    public static void main(String[] args) {
        SpringApplication.run(AutowireWithMainClassApplication.class, args);
        String city;
        //this will not work, compilation error
        //Cannot make a static reference to the non-static field zipCodeLookupService
        city=zipCodeLookupService.retriveCityForZip(args[0]);

        System.out.println("city for zipcode " + args[0] + " is " +city);       
    }
}

Could someone suggest - how or what is the correct way of using autowiring when main class is involved.

(As making the Autowired reference as static does not work anyway)
in AutowireWithMainClassApplication class, changing to -

@Autowired
static IZipCodeLookup zipCodeLookupService;

throws

Exception in thread "main" java.lang.NullPointerException

like image 412
samshers Avatar asked Oct 07 '17 05:10

samshers


People also ask

Can we use Autowired in method?

@Autowired can be used only on "a constructor, field, setter method or config method".

Where we can use @autowired annotation?

Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built on dependency injection and we inject the class dependencies through spring bean configuration file.

How do I use Autowiring?

Enabling @Autowired annotation Spring beans can be declared either by Java configuration or XML configuration. By declaring beans, you provide metadata to the Spring Container to return the required dependency object at runtime. This is called Spring Bean Autowiring.

How does @autowired works internally?

Autowiring feature of spring framework enables you to inject the object dependency implicitly. It internally uses setter or constructor injection. Autowiring can't be used to inject primitive and string values. It works with reference only.


1 Answers

You can do one of the following:

  1. Use the @Autowired object in a @PostConstruct method, which is executed after dependency injection is done, as davidxxx explained above

  2. Use Spring's getBean() in your main() to explicitly ask Spring framework to return the object after the injection completes:

    public static void main(String[] args) {
        ...
        ConfigurableApplicationContext appContext = SpringApplication.run(StartApplication.class, args);
        IZipCodeLookup service = appContext.getBean(IZipCodeLookup.class);
        ...
    }
    
  3. Use Spring's CommandLineRunner component (runs right after main), which will be responsible on autowiring your object:

    @Component
    public class MyRunner implements CommandLineRunner {
    
        @Autowired
        private IZipCodeLookup service;
    
        @Override
        public void run(String... args) throws Exception {
            ...
            service.doSomething();
            ... 
        }
    }
    
  4. Implement Spring's ApplicationRunner's run method in your main:

    @SpringBootApplication
    public class StartApplication implements ApplicationRunner {
    
        @Autowired
        private IZipCodeLookup service;
    
        public static void main(String[] args) {
            ConfigurableApplicationContext appContext = SpringApplication.run(StartApplication.class, args);
        }
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            ...
            service.doSomething();
            ... 
        }
    }
    
like image 129
Naor Bar Avatar answered Nov 15 '22 10:11

Naor Bar