在编写@Configuration配置类时,我们可能会看到proxyBeanMethods=false这样的属性配置。这篇文章就基于实际结果来总结其作用。

show me your code

  1. 两个Bean定义

    1. public class MyBean1 {
    2. private MyBean2 myBean2;
    3. @PostConstruct
    4. public void testPostConstruct(){
    5. System.err.println(getClass()+"postConstruct");
    6. }
    7. public void setMyBean2(MyBean2 myBean2) {
    8. this.myBean2 = myBean2;
    9. System.out.println("MyBean2: "+myBean2);
    10. }
    11. }

    ```json public class MyBean2 {

    @PostConstruct public void testPostConstruct(){

    1. System.err.println(getClass()+"postConstruct");

    }

}

  1. 2. 配置两个Bean
  2. ```json
  3. @Configuration(proxyBeanMethods = false)
  4. public class MyConfiguration {
  5. @Bean
  6. public MyBean1 myBean1(){
  7. MyBean1 myBean1 = new MyBean1();
  8. myBean1.setMyBean2(myBean2());
  9. myBean1.setMyBean2(myBean2());
  10. return myBean1;
  11. }
  12. @Bean
  13. public MyBean2 myBean2(){
  14. System.out.println("myBean2()方法执行了");
  15. return new MyBean2();
  16. }
  17. }

show me the result

proxyBeanMethods=true

image.png
结果解释:

  1. myBean2()MyBean2注册到IoC容器时执行了一次
  2. 之后myBean1()方法执行,set了两次myBean2()。结果两次都是同一个MyBean2
  3. MyBean1MyBean2都走了一次生命周期

    proxyBeanMethods=false

    image.png

  4. 第一次myBean2()执行是myBean1()方法触发的首次set

  5. 第二次myBean2()执行是myBean1()方法触发的第二个set
  6. 第三次myBean2()执行是MyBean2注册到IoC容器时触发执行,走了一个生命周期
  7. 第一次和第二次返回的MyBean2完全不一样

    conclusion

  8. proxyBeanMethods=true

    • 直接调用@Bean方法后,走的是从容器获取
  9. proxyBeanMethods=false
    • 直接调用@Bean方法后,和调用普通方法没区别
  10. SpringBoot2.2后默认为true
  11. 底层原理是@Bean方法是否被CGLib代理
    • true:代理的话就走容器
    • false:不代理的话就和调用普通方法一样
  12. false可以提高性能,前提是确定不会被直接方法调用