Reputation:
I apologize beforehand if this question has already been answered before or if its too easy, but I am relatively new to spring as a DI framework and I have the following problem
@Bean
public EnvironmentInfo environmentInfo() {
return new EnvironmentInfo();
}
@Bean(name = "availabilityZone")
@Autowired
public Optional<String> getAvailabilityZone(EnvironmentInfo envInfo) {
return envInfo.getAvailabilityZone(); // this returns an Optional<String>
}
And then I autowire it in elsewhere like this
@Autowired
@Named("availabilityZone")
protected Optional<String> availabilityZone;
Now I put a log statement in the getAvailabilityZone and confirmed its called and it evaluates to a Optional with a proper availability zone. However the autowire itself evaluates to Optional.empty
My question is, is there something I am missing from the Autowiring to vend the Optional correctly?
Edit
The problem effectively goes away if I do this
@Bean(name = "availabilityZone")
@Autowired
public String getAvailabilityZone(EnvironmentInfo envInfo) {
return envInfo.getAvailabilityZone().getOrElse("N/A");
}
@Autowired
@Named("availabilityZone")
protected String availabilityZone;
Upvotes: 2
Views: 1267
Reputation: 981
Autowiring an optional has another meaning, that is why it does not work as you hoped.
I used it in cases where eg. a JavaMailSender
was not guaranteed to be available but if it was it was available as an JavaMailSender
injecting worked than as:
@Autowired
protected Optional<JavaMailSender> mailSender;
The worst answer is that the following works (at least in the most recent spring-boot):
@Service
public class TestController {
@Autowired
TestController(@Named("availabilityZone") Optional<Optional<String>> availabilityZone) {
System.out.println(availabilityZone);
}
}
But this makes me cry...
Another option which is a little bit better is:
@Bean(name = "availabilityZone")
@Autowired
public String getAvailabilityZone(EnvironmentInfo envInfo) {
return envInfo.getAvailabilityZone().orElse(null);
}
Another solution would be wrapping it in some custom object, but I think returning null for your bean would be good enough.
Upvotes: 3