Home > Software design >  why I always get singleton bean, even if I use proxyBeanMethods = false?
why I always get singleton bean, even if I use proxyBeanMethods = false?

Time:12-25

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.

  • Related