@Configuration(proxyBeanMethods = true)

本文简要总结下SpringBoot配置类使用的注解@Configuration的属性proxyBeanMethods属性的作用

(2) 给IOC容器中导入组件有如下几种方式:

    /**
     * 给容器中添加组件的几种方式:
     * 1. 包扫描+组件标注注解的方式:@ComponentScan + 注解(@Controller,@Service,@Repository,@Component),局限性在于只有我们自己写的类才能使用此种方式
     * 2. @Bean注解导入第三方包里面的组件:在配置类中,使用@Bean注解给容器添加组件,好处是可以导入第三方的组件到容器中
     * 3. @Import快速给容器中导入一个组件
     *      3.1、@Import(要导入到容器中的组件),id默认是组件的全类名
     *      3.2、@Import(使用ImportSelector导入需要的组件的全类名)
     *      3.3、@Import(使用ImportBeanDefinitionRegister手动注册bean到容器中)
     * 4. 通过Spring提供的FactoryBean向容器中注入组件
     *      4.1、 默认获取到的似乎工程bean调用getObject创建的对象
     *      4.2、 要获取工厂Bean本身,需要给id前面加一个&,如&colorFactoryBean
     * 5.使用@ImportResource注解导入xml配置文件(可以把古老项目中在xml中配置的bean组件导入到IOC    
         容器中来)
     */

(2)首先,明确的一点是,使用了@Configuration注解的配置类的目的是给IOC容器中添加组件,在配置类中使用@Bean注解标注在方法上:

Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {

    /**
     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     * @return
     */

    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User user = new User("zhangSan", 18);
        //user组件依赖了Pet组件
        user.setPet(tomcatPet());
        return user;
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }

}

(3)要研究的问题是:@Configuration注解的proxyBeanMethods属性取值true和false的区别:

  • 【Full模式】当proxyBeanMethods=true时,外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象,也就是说,保证每个@Bean方法被调用多少次返回的组件都是单例的,所以如果proxyBeanMethods=true时,每次从外部调用@Bean方法时,都会进行判断操作,判断容器中是否有这个组件,会比较耗时,也即Full模式
  • 【Lite模式】当proxyBeanMethods=false时,每个@Bean方法被调用多少次返回的组件都是新创建的,即,当从外部调用@Bean方法时,不会去判断容器中是否有这个组件,而是直接新创建一个组件然后返回,比Full模式效率高。
  • 总结就是:如果配置类中的组件有依赖关系,则应该使用Full模式,即【proxyBeanMethods=true】,否则应该使用Lite模式,即【proxyBeanMethods=false】
  • 补充说明

那自然会想到SpringBoot项目的主配置类也是一个配置类啊,那主配置类使用的是什么模式呢(即:主配置类使用的是Full模式还是Lite模式呢),查看主配置类发现其采用的是Full模式,如下图:

@Configuration(proxyBeanMethods = true)_第1张图片

你可能感兴趣的:(Java,spring,boot,后端,java)