zoukankan      html  css  js  c++  java
  • @Configuration属性proxyBeanMethods详解

    @Configuration注释中的proxyBeanMethods参数是springboot1.0,升级到springboot2.0之后新增的比较重要的内容,该参数是用来代理bean的。

    理论

    首先引出两个概念:Full 全模式,Lite 轻量级模式

    Full(proxyBeanMethods = true) :proxyBeanMethods参数设置为true时即为:Full 全模式。 该模式下注入容器中的同一个组件无论被取出多少次都是同一个bean实例,即单实例对象,在该模式下SpringBoot每次启动都会判断检查容器中是否存在该组件
    Lite(proxyBeanMethods = false) :proxyBeanMethods参数设置为false时即为:Lite 轻量级模式。该模式下注入容器中的同一个组件无论被取出多少次都是不同的bean实例,即多实例对象,在该模式下SpringBoot每次启动会跳过检查容器中是否存在该组件
    什么时候用Full全模式,什么时候用Lite轻量级模式?
    当在你的同一个Configuration配置类中,注入到容器中的bean实例之间有依赖关系时,建议使用Full全模式
    当在你的同一个Configuration配置类中,注入到容器中的bean实例之间没有依赖关系时,建议使用Lite轻量级模式,以提高springboot的启动速度和性能

    proxyBeanMethods 属性默认值是 true, 也就是说该配置类会被代理(CGLIB),在同一个配置文件中调用其它被 @Bean 注解标注的方法获取对象时会直接从 IOC 容器之中获取;

    看下源码注解

    	/**
    	 * Specify whether {@code @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 {@code @Bean} method calls in user code. This feature
    	 * requires method interception, implemented through a runtime-generated CGLIB
    	 * subclass which comes with limitations such as the configuration class and
    	 * its methods not being allowed to declare {@code final}.
    	 * <p>The default is {@code true}, allowing for 'inter-bean references' via direct
    	 * method calls within the configuration class as well as for external calls to
    	 * this configuration's {@code @Bean} methods, e.g. from another configuration class.
    	 * If this is not needed since each of this particular configuration's {@code @Bean}
    	 * methods is self-contained and designed as a plain factory method for container use,
    	 * switch this flag to {@code false} in order to avoid CGLIB subclass processing.
    	 * <p>Turning off bean method interception effectively processes {@code @Bean}
    	 * methods individually like when declared on non-{@code @Configuration} classes,
    	 * a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore
    	 * behaviorally equivalent to removing the {@code @Configuration} stereotype.
    	 * @since 5.2
    	 */
    	boolean proxyBeanMethods() default true;
    
    

    注解的意思是 proxyBeanMethods 配置类是用来指定 @Bean 注解标注的方法是否使用代理,默认是 true 使用代理,直接从 IOC 容器之中取得对象;如果设置为 false, 也就是不使用注解,每次调用 @Bean 标注的方法获取到的对象和 IOC 容器中的都不一样,是一个新的对象,所以我们可以将此属性设置为 false 来提高性能;

    根据注释 proxyBeanMethods 是为了让使用 @Bean 注解的方法被代理而实现 bean 的生命周期的行为。

    1. 设置为 true,那么直接调用方法获取 bean,不会创建新的 bean,而是会走 bean 的生命周期的行为。
    2. 设置为 false, 那么直接调用方法获取 bean,会创建新的 bean,且不会走 bean 的生命周期的行为。

    Configuration 源码

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Configuration {
            @AliasFor(annotation = Component.class)
            String value() default "";
            boolean proxyBeanMethods() default true;
    
    }
    
    
    

    测试验证代码

    测试代码

    public class AnnotationConfigApplicationContextTest {
        @Test
        public void refresh(){
            AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext();
            ctx.register(AppConfig.class);
            ctx.refresh();
            MyBean myBean=ctx.getBean(MyBean.class);
            myBean.sayHello();
            YourBean yourBean=ctx.getBean(YourBean.class);
            yourBean.sayHello();
        }
    }
    
    
    

    Configuration 代码,设置为 false

    @Configuration(proxyBeanMethods = false)
    public class AppConfig {
        @Bean
        public MyBean myBean(){
            return new MyBean();
        }
        @Bean
        public YourBean yourBean(){
            return new YourBean(myBean());
        }
    }
    
    
    
    

    Mybean 代码

    public class MyBean {
        public MyBean(){
            System.out.println("MyBean construct......");
        }
        @PostConstruct
        public void init(){
             System.out.println("MyBean PostConstruct ....");
        }
        public void sayHello(){
             System.out.println("Hi MyBean ,hello world!");
        }
    }
    
    
    

    YourBean 代码

    public class YourBean {
        public MyBean myBean;
    
       public YourBean(MyBean myBean){
           System.out.println("YourBean construct...");
           this.myBean=myBean;
       }
        @PostConstruct
        public void init(){
            System.out.println("YourBean PostConstruct...");
        }
        public void sayHello(){
            System.out.println("Hi YourBean ,hello world!");
        }
    }
    
    
    

    执行 refresh 测试测试代码结果(proxyBeanMethods = false)

    MyBean construct...... 打印了两次,说明被 new 了两次

    10:04:56.066 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myBean'
    MyBean construct......
    MyBean PostConstruct ....
    10:04:56.069 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'yourBean'
    MyBean construct......
    YourBean construct...
    YourBean PostConstruct...
    Hi MyBean ,hello world!
    Hi YourBean ,hello world!
    
    
    
    

    执行 refresh 测试测试代码结果(proxyBeanMethods = true)

    MyBean construct...... 只打印了一次,说明只被 new 了一次。

    10:06:51.727 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myBean'
    MyBean construct......
    MyBean PostConstruct ....
    10:06:51.741 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'yourBean'
    YourBean construct...
    YourBean PostConstruct...
    Hi MyBean ,hello world!
    Hi YourBean ,hello world!
    
    
    
  • 相关阅读:
    从寻找资源的习惯上谈如何获得好的代码及控件(使用Koders查找)
    数据仓库的一些基本知识2
    淘宝API开发系列商家的绑定
    淘宝API开发系列开篇概述
    读取实体类的属性的备注作为表头的应用
    设置Windows服务允许进行桌面交互,实现屏幕监控
    C#进行Visio二次开发之组合形状操作
    吉日嘎啦通用权限管理系统解读及重构升华高度封装的编辑窗体
    WinForm界面开发之模块化分合
    CLR中的内存管理
  • 原文地址:https://www.cnblogs.com/hanlk/p/14479879.html
Copyright © 2011-2022 走看看