Search code examples
javaspringspring-bootinversion-of-control

Configuration properties not autowired when used in request body?


I'm using a particular class (ClassA) in my controller as the request body, but within that class, my autowired ConfigurationProperties is null.

Controller:

@RestController
@RequestMapping(value = "/rest/v1/")
public class XyzController {

    @Autowired
    ServiceXyz serviceXyz;

    @PostMapping(value = "/route")
    public void route(@RequestBody ClassA classA) {
        serviceXyz.methodAbc(classA);
    }
}

ServiceXYZ:

@Service
public class ServiceXyz {

    public boolean methodAbc(ClassA classA) {
        return classA.methodA() && otherStuff();
    }
}

ClassA.java:

@Component
public class ClassA {

    @Autowired
    ApplicationProperties applicationProperties;

    public boolean methodA() {
        return fieldA.equals(applicationProperties.someProperty());
    }
}

ApplicationProperties.java:

@Component
@ConfigurationProperties(prefix="stuff")
public class ApplicationProperties {
    // etc.
}

It's within ClassA.methodA that applicationProperties is null, even though everybody is marked with the correct annotations, and autowiring is working throughout the rest of the application.

Is it possible that this just doesn't work?


Solution

  • Autowiring works for objects from Spring context. In your request object of ClassA is parsed from JSON I think and is not taken from Spring context. You'd better change your code to make ClassA as simple DTO and inject ApplicationProperties into your service class.

    You can change your ClassA to this

    public class ClassA {
    
      public boolean methodA(ApplicationProperties applicationProperties) {
          return fieldA.equals(applicationProperties.someProperty());
      }
    }
    

    And your service to this:

    @Service
    public class ServiceXyz {
    
      @Autowired
      private ApplicationProperties applicationProperties;
    
      public boolean methodAbc(ClassA classA) {
        return classA.methodA(applicationProperties) && otherStuff();
      }
    }