Issue
I am new to the spring boot framework and I have some confusion regarding the @Bean annotation and how the instance variable gets changed by the Bean. I have a below example and if someone can answer my questions will be really helpful:
- If I am defining restTemplate in my instance variable will userRestTemplate template bean will be able to change its value?
- If userRestTemplate is changing its value then userDetail will have the updated value by userRestTemplate bean?
- If not what will be userdetail bean will be setting in setTemplate method?
@Configuration
public class UserConfiguration{
RestTemplate restTemplate;
@Bean
@Named("userRestTemplate")
public RestTemplate userRestTemplate(RestTemplateBuilder restTemplateBuilder) {
RestTemplate restTemplate = restTemplateBuilder.build();
//restTemplate.getMessageConverters().add(0, createMappingJacksonHttpMessageConverter());
this.restTemplate = restTemplate;
return restTemplate;
}
@Bean
public UserDetail userDetail() {
UserDetail user = new UserDetail();
user.setTemplate(restTemplate);
return user;
}
}
Solution
Actually, I don't think this is the standard way of creation.
As when you annotate the method with @Bean
, you mean you want to ask Spring to help you to manage the bean. Therefore it makes no sense to store the bean instance by yourself as a local variable.
Instead of storing the instance in the class field, you should ask Spring to give you the instance instead.
There are multiple ways to do that.
- Specify
RestTemplate
as a parameter in@Bean
method. In case you have asked Spring to manage multiple RestTemplate instance, which is possible. Then you should specify the parameter name same as@Named
which isuserRestTemplate
, so that Spring can find the correct restTemplate properly.
@Configuration
public class UserConfiguration{
@Bean
@Named("userRestTemplate")
public RestTemplate userRestTemplate(RestTemplateBuilder restTemplateBuilder) {
RestTemplate restTemplate = restTemplateBuilder.build();
// this.restTemplate = restTemplate; // no this restTemplate instance setting;
return restTemplate;
}
@Bean
public UserDetail userDetail(RestTemplate userRestTemplate) {
UserDetail user = new UserDetail();
user.setTemplate(userRestTemplate);
return user;
}
}
- Use
@Autowired
Annotation.
@Configuration
public class UserConfiguration{
@Autowired
private RestTemplate restTemplate;
@Bean
@Named("userRestTemplate")
public RestTemplate userRestTemplate(RestTemplateBuilder restTemplateBuilder) {
RestTemplate restTemplate = restTemplateBuilder.build();
//restTemplate.getMessageConverters().add(0, createMappingJacksonHttpMessageConverter());
// this.restTemplate = restTemplate; // again no setting this, okay.
return restTemplate;
}
@Bean
public UserDetail userDetail() {
UserDetail user = new UserDetail();
user.setTemplate(restTemplate);
return user;
}
}
The advantage of asking Spring to manage java beans, instead of managing by ourselves.
You would have the advantage to use Spring AOP
, ...
Answered By - CHANist