@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 容器之中获取;
注解的意思是 proxyBeanMethods 配置类是用来指定 @Bean 注解标注的方法是否使用代理,默认是 true 使用代理,直接从 IOC 容器之中取得对象;如果设置为 false, 也就是不使用注解,每次调用 @Bean 标注的方法获取到的对象和 IOC 容器中的都不一样,是一个新的对象,所以我们可以将此属性设置为 false 来提高性能;
根据注释 proxyBeanMethods 是为了让使用 @Bean 注解的方法被代理而实现 bean 的生命周期的行为。
设置为 true,那么直接调用方法获取 bean,不会创建新的 bean,而是会走 bean 的生命周期的行为。
设置为 false, 那么直接调用方法获取 bean,会创建新的 bean,且不会走 bean 的生命周期的行为。
测试验证代码
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!");
}
}