now I am learning SpringBoot. really got confused about the annotation @Configuration(proxyBeanMethods = false)
I defined an configuration class like the following,
@Configuration(proxyBeanMethods = false)
public class BeanConfiguration {
@Bean("User")
@ConfigurationProperties(prefix = "user2")
public User getUser(){
return new User();
}
}
I thought every bean will be different, cause it doesn't work in singleton mode.
but the test code shows me a different idea.
@SpringBootApplication
public class Boot2InitializrApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Boot2InitializrApplication.class, args);
User user1 = (User)applicationContext.getBean(User.class);
User user2 = (User)applicationContext.getBean(User.class);
System.out.println((user1 == user2)); **//here ? always true. even if I set 'proxyBeanMethods = false' .**
BeanConfiguration bean = applicationContext.getBean(BeanConfiguration.class);
User user3 = bean.getUser();
User user4 = bean.getUser();
System.out.println(user3==user4); //here, it varies when proxyBeanMethods is set true or/false.
}
}
Why does the bean I get through applicationContext always work under singleton mode?
CodePudding user response:
According to the reference documentation that is actually the expected behavior:
Specify whether @Bean methods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct @Bean method calls in user code.
This means that @Configuration(proxyBeanMethods = false)
has only an effect when you call getUser()
method directly, hence System.out.println((user1 == user2));
is always true because you are not calling the @Bean
method directly but instead relying on Spring to return to you the needed Bean (which will be the same since Spring-managed Beans are Singleton by default).
Regarding System.out.println(user3==user4)
it will be true when you use @Configuration(proxyBeanMethods = true)
, because this means that Spring-managed Beans lifecycle will be enforced and thus even if you call getUser()
method directly, it will return the same Bean. It will return false if you use @Configuration(proxyBeanMethods = false)
, because by then Spring-managed Beans lifecycle will not be enforced and a brand new User
will be created and returned.