Search code examples
javaspringspring-bootspring-mvcspring-restcontroller

Getting null for Autowired bean created using Java config


I am creating a REST service in Spring boot. I am creating a bean in config class and trying to use in service class by auto wiring, but I am always getting null, I have tried in constructor injection as well but not working. Below is the code,

Main app

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

REST controller

@RestController
@RequestMapping("/v1")
public class RestController {

    @Autowired
    private Service service;

Service

@Service
public class ServiceImpl implements Service {
    //This is the bean
    @Autowired
    private Record record;
    
    public ServiceImpl() {   //-----------------> tried injecting in constructor as well
        System.out.println(record); //-------------------> null
    }

Config class

@Configuration
public class AppConfig {
    
    @Bean
    public Record record() {
        return new Record("test");
    }
}

I noted whenever I remove the record() from config class I get below error

required a bean of type 'com.ns.service.Record' that could not be found

And after adding the method the error is not reported but null is returned, which indirectly means record() is considered as returning the required bean. I can't find what I am doing wrong please advise.

Project folder structure Project folder structure


Solution

  • I think you're doing everything right conceptually

    Spring creates an object first and only after that injects the values (technically done in bean post processors):

    So try this:

    @Service
    public class ServiceImpl implements Service {
        //This is the bean
        @Autowired
        private Record record;
        
        public ServiceImpl() {   
            // here the record is null - not injected yet
            System.out.println(record); 
        }
    
        @PostConstruct
        public void checkThisOut() {
          // here print the record
        }
    

    You say you've tried constructor injection as well - it should work because spring has to inject something into the constructor of a bean (ServiceImpl) or fail. Please show the code snippet

    One this that might be wrong in some level (although it doesn't sound like this from your description) is that you have to put all the @Configuration/@Service annotated classes in the package that is the same or underneath the package where you've created the main class annotated with @SpringBootApplication annotation. It instructs spring boot where to look for the beans.

    So make sure your classes obey this rule...