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
@Autowired can be used only on "a constructor, field, setter method or config method".
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.
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.
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.
You can do one of the following:
Use the @Autowired object in a @PostConstruct method, which is executed after dependency injection is done, as davidxxx explained above
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);
...
}
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();
...
}
}
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();
...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With