@Configuration(proxyBeanMethods = false) what's the use of setting this to false

Recently, looking at the source code of Nacos, I found that @ Configuration(proxyBeanMethods = false) on many Configuration classes set proxyBeanMethods to false. Special research.

 

The default value in the source code is true. You can probably know the explanation of this attribute.

If 1: is true, it means that the method marked by @Bean will be surrogate by CGLIB, and it will take some actions in the life cycle of bean (for example, the lifecycle provided by spring such as @PostConstruct,@Destroy). If bean is a singleton, then it will be called in the same configuration.

The method identified by @ bean gets the same bean no matter how many times it is called, that is, the bean is initialized only once.

2: If false, the method identified by @ bean will not be intercepted for CGLIB proxy, It will not take some behavior in the bean's life cycle (for example, the lifecycle provided in spring such as @PostConstruct,@Destroy, etc.), if the method of calling @Bean identification in the same configuration is just the execution of common method, it will not get objects from the container, so if the method of calling @Bean ID individually is the common method call, and it does not take the bean life cycle.

Therefore, if there is no dependent call between the methods identified by @ bean in the configuration class, it can be set to false, which can avoid intercepting methods for proxy operation, and is also an optimization to improve performance. However, it should be noted that the return value object identified by @ bean will still be put into the container. The bean obtained from the container can still be a singleton and will go through the life cycle.

Take the following example:

public class MyBean {
    @PostConstruct
    public void init(){
        System.out.println("MyBean Initialized");
    }
    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 Initialized");
    }

    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());
    }
}

 

Test method:

@Component
public class InitClass implements InitializingBean , ApplicationContextAware {

    ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        YourBean bean = this.applicationContext.getBean(YourBean.class); // first line
        YourBean bean1 = this.applicationContext.getBean(YourBean.class);  // Second line
        MyBean myBean = this.applicationContext.getBean(MyBean.class);    // Third line
        myBean.hello();
        bean.hello();
        bean1.hello();
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
}

 

The first line is completed: both MyBean and YourBean have been initialized, indicating that myBean() has gone through the bean life cycle in new YourBean (myBean()), indicating that it has been proxy by CGLIB.

 

Second, after the execution of the three lines, there is no content output, indicating that both YourBean and MyBean are initialized once.

 

 

@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());
    }
}

 

After executing the first line, only YourBean initialization has output: see that the MyBean attribute inside is @ 5351

 

After executing the second line, there is no content output, and the MyBean attribute in bean1 is also @ 5351

 

After the third line is executed, the initialization of MyBean is output, and the bean obtained from the container is @ 5360

You should realize the meaning of proxybean methods. When it is false, the method call identified by @ Bean is an ordinary method call and will not be proxy.

 

Keywords: Spring

Added by d99kg on Wed, 29 Dec 2021 01:52:48 +0200