I have a strange problem reading configuration, none of solutions I've seen seem to work. Here is my code:
@SpringBootApplication
@EnableConfigurationProperties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Here is my properties class
@Component
@ConfigurationProperties(prefix = "my")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class MyProperties {
private String host;
private int port;
}
I then use MyProperties class in my class using @Autowired:
@Autowired
private MyProperties props;
However, I'm getting null for my props object.
Strangely, this is passing the tests just perfectly:
@SpringBootTest
class ApplicationTests {
@Autowired
private MyProperties props;
@Test
void test_configuration() {
Assertions.assertEquals(props.getHost(), "xx.xx.xx.xx");//pass!
Assertions.assertEquals(props.getPort(), xxxxxx);//pass!
}
}
It has totally refused to work, and so has @Value injection. What could I be missing?
EDIT
Here's complete code of how I'm using @Autowired on MyProperties (I've included @Value which is also not working)
@Slf4j
@Component //also tried @Configurable, @Service
public class MyService {
@Autowired
private MyProperties props;
@Value("localhost")
public String host;
public void post() {
log.info(host props);// =null and null
}
}
EDIT2
However, I've noticed that on the controller, it works perfectly okay:
@Slf4j
@RestController
@Service
public class Main {
@Autowired
private MyProperties props;
@Value("localhost")
private String host;
@GetMapping("/post")
public void post() {
log.info(host props);//=it's perfect!
new MyService().post();// calling MyService - where @Autowired or @Value is failing
}
}
CodePudding user response:
The reason this isn't working is because the MyService
you're using isn't a Spring bean, but an instance you created by yourself (using new MyService()
).
To make this work, you should autowire MyService
, in stead of creating your own instance:
@Slf4j
@RestController
public class Main {
@Autowired // Autowire MyService
private MyService myService;
@GetMapping("/post")
public void post() {
myService.post(); // Use the myService field
}
}
For more information, look at this Q&A: Why is my Spring @Autowired field null.
CodePudding user response:
1. Lombok
Some people use Project Lombok to add getters and setters automatically. Make sure that Lombok does not generate any particular constructor for such a type, as it is used automatically by the container to instantiate the object.
With "such a type" ConfigurationProperties
is referred in Externalized Configuration (one of my favorite chapters;) More Exact: 2.8.1. JavaBean properties binding, at the bottom of second "Note!" ;)
So this could be a reason (for strange behavior).