核心现象同一个类里面Bean方法互相调用Full拿单例Lite新建对象1. 两个简单BeanpublicclassABean{}publicclassBBean{publicABeanaBean;publicBBean(ABeanaBean){this.aBeanaBean;}}2. Full模式Configurationimportorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;Configuration// Full模式CGLIB代理publicclassFullConfig{BeanpublicABeanaBean(){System.out.println(Full - 创建ABean);returnnewABean();}BeanpublicBBeanbBean(){// 在配置类内部调用 aBean()ABeanaaBean();returnnewBBean(a);}}3. Lite模式Component Beanimportorg.springframework.context.annotation.Bean;importorg.springframework.stereotype.Component;Component// Lite模式无CGLIB代理publicclassLiteConfig{BeanpublicABeanaBean(){System.out.println(Lite - 创建ABean);returnnewABean();}BeanpublicBBeanbBean(){// 普通java方法调用ABeanaaBean();returnnewBBean(a);}}4. 启动类 测试importorg.springframework.boot.CommandLineRunner;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.context.ApplicationContext;SpringBootApplicationpublicclassBeanDemoAppimplementsCommandLineRunner{publicstaticvoidmain(String[]args){SpringApplication.run(BeanDemoApp.class,args);}Overridepublicvoidrun(String...args)throwsException{ApplicationContextctxBeanDemoApp.this;// FullConfigBBeanfullBctx.getBean(bBean,BBean.class);ABeanfullActx.getBean(aBean,ABean.class);System.out.println(Full模式bBean里面的aBean 和容器aBean是否同一个(fullB.aBeanfullA));// LiteConfigBBeanliteBctx.getBean(liteConfig.bBean,BBean.class);ABeanliteActx.getBean(liteConfig.aBean,ABean.class);System.out.println(Lite模式bBean里面的aBean 和容器aBean是否同一个(liteB.aBeanliteA));}}控制台输出结果Full - 创建ABean Full模式bBean里面的aBean 和容器aBean是否同一个true Lite - 创建ABean Lite - 创建ABean Lite模式bBean里面的aBean 和容器aBean是否同一个false解读Full(Configuration)bBean()里调用aBean()不是直接执行方法而是被代理拦截从Spring容器返回已存在的单例只实例化一次。Lite(Component Bean)没有代理bBean()调用aBean()就是普通Java方法执行new了两次ABean一次是bBean构造用的一次是Spring扫描Bean注册的两个对象地址不一样。⚠️ 注意如果不通过内部方法调用只是单独定义一堆互不引用的BeanLite模式看起来一切正常坑藏在内部互相调用场景。补充Spring 6 / SpringBoot3 新变化Spring6 引入Configuration(proxyBeanMethods false)Configuration(proxyBeanMethodsfalse)publicclassConfig{Bean...}这个也是Lite模式虽然写了Configuration但是关闭代理内部方法调用同样会新建对象。现在SpringBoot很多自动配置都用这个好处不需要CGLIB启动更快代价就是不能内部调用Bean方法。