@Configuration(proxyBeanMethods = false) 設置這個為false有啥用


最近看Nacos的源碼,發現很多Configuration配置類上  @Configuration(proxyBeanMethods = false)   都把proxyBeanMethods設置成了false了。特地研究下。

 

 源碼中默認是true,對這個屬性的解釋也可以大概知道。

1: 如果為true, 則表示被@Bean標識的方法都會被CGLIB進行代理,而且會走bean的生命周期中的一些行為(比如:@PostConstruct,@Destroy等 spring中提供的生命周期), 如果bean是單例的,那么在同一個configuration中調用

    @Bean標識的方法,無論調用幾次得到的都是同一個bean,就是說這個bean只初始化一次。

2:  如果為false,則標識被@Bean標識的方法,不會被攔截進行CGLIB代理,也就不會走bean的生命周期中的一些行為(比如:@PostConstruct,@Destroy等 spring中提供的生命周期),如果同一個configuration中調用@Bean標識的方法,就只是普通方法的執行而已,並不會從容器中獲取對象。所以如果單獨調用@Bean標識的方法就是普通的方法調用,而且不走bean的生命周期。

所以,如果配置類中的@Bean標識的方法之間不存在依賴調用的話,可以設置為false,可以避免攔截方法進行代理操作,也是提升性能的一種優化。但是需要注意,@Bean標識的返回值對象還是會放入到容器中的,從容器中獲取bean還是可以是單例的,會走生命周期。

看下面的例子:

public class MyBean {
    @PostConstruct
    public void init(){
        System.out.println("MyBean初始化了");
    }
    public void hello(){
        System.out.println("Mybean  hello");
    }
}
public class YourBean {

    public MyBean myBean;

    public YourBean(MyBean myBean){
         this.myBean=myBean;
    }

    @PostConstruct
    public void init(){
        System.out.println("YourBean 初始化了");
    }

    public void hello(){
        System.out.println("YourBean hello");
    }
}

 

@Configuration(proxyBeanMethods=true)

@Configuration(proxyBeanMethods = true)
public class ConfigureTest {
    @Bean
    public OrderEntity getOrderEntity(){
        return new OrderEntity();
    }

    @Bean
    public MyBean myBean(){
        return new MyBean();
    }

    @Bean
    public YourBean yourBean(){
       return new YourBean(myBean());
    }
}

 

測試方法:

@Component
public class InitClass implements InitializingBean , ApplicationContextAware {

    ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        YourBean bean = this.applicationContext.getBean(YourBean.class); // 第一行
        YourBean bean1 = this.applicationContext.getBean(YourBean.class);  // 第二行
        MyBean myBean = this.applicationContext.getBean(MyBean.class);    // 第三行
        myBean.hello();
        bean.hello();
        bean1.hello();
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
}

 

第一行執行完:MyBean和YourBean都進行初始化了,說明在new YourBean(myBean())中myBean()走了bean的生命周期,說明被CGLIB進行代理了。

 

 第二,三行執行完,沒什么內容輸出,說明YourBean,MyBean都初始化一次。

 


 

@Configuration(proxyBeanMethods=false)

@Configuration(proxyBeanMethods = false)
public class ConfigureTest {
    @Bean
    public OrderEntity getOrderEntity(){
        return new OrderEntity();
    }

    @Bean
    public MyBean myBean(){
        return new MyBean();
    }

    @Bean
    public YourBean yourBean(){
       return new YourBean(myBean());
    }
}

 

執行完第一行,只有YourBean初始化有輸出:看到里面的MyBean屬性是@5351

 

 執行完第二行,沒有內容輸出,bean1中的MyBean屬性也是@5351

 

 第三行執行完,MyBean的初始化才輸出,而且從容器中得到的這個bean是@5360

看到這里應該能體會到,proxyBeanMethods的含義了吧。為false的時候,@Bean標識的方法調用就是普通的方法調用,不會被代理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM