当前位置: 首页 > news >正文

Spring小知识点

Spring小知识点

@Configuration

从spring-context5.2版本开始,加了一个proxyBeanMethods属性

public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";/*** 该属性为true时,被@Configuration注解的配置类将会使用CGLIB增强,* 这样使得直接调用@Bean注解的方法将会返回同一个实例* 如果不需要这个特性,可以设置成false,默认为true* @since 5.2*/boolean proxyBeanMethods() default true;}

例子:

@Configuration(proxyBeanMethods = false)
public class AppConfig {}

当打印bean的class属性时,为class com.wangtao.springboottest.config.AppConfig,即没有被代理。

@Configuration
public class AppConfig {}

当打印bean的class属性时,为class com.wangtao.springboottest.config.AppConfig$$EnhancerBySpringCGLIB$$b73b4e3,发现被CGLIB代理。

再来看看方法行为

@Configuration
public class AppConfig {@Beanpublic A beanA() {return new A();}@Beanpublic B beanB() {// 直接调用方法,而不是注入的方式A a = beanA();return new B(a);}public static class A {}public static class B {public A a;public B(A a) {this.a = a;}}
}

会发现容器中的A实例与B实例的成员变量a是同一个对象。当然如果手动设置proxyBeanMethods = false,那么就是两个对象了。

最后,增强配置类的逻辑位于ConfigurationClassPostProcessor类中

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {int factoryId = System.identityHashCode(beanFactory);if (this.factoriesPostProcessed.contains(factoryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);}this.factoriesPostProcessed.add(factoryId);if (!this.registriesPostProcessed.contains(factoryId)) {// BeanDefinitionRegistryPostProcessor hook apparently not supported...// Simply call processConfigurationClasses lazily at this point then.processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);}// 增强配置类enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

注:
只有被@Configuration注解的配置类并且proxyBeanMethods=true时才会被增强,其他情况都不会有该特性,如@Compoment注解的类等。

@Bean

使用@Bean注解注册的bean不会被当成配置类来解析。

比如以下例子

/*** 注意: 该类不要放在Spring Boot扫描的包下面, 因为要使用@Bean的方式注册到容器中*/
@Configuration
public class AppConfig {@Beanpublic A beanA() {return new A();}
}/*** 注意: 该类需要放在Spring Boot扫描的包下面,作为配置类*/
@Configuration
public class MainConfig {/*** 注册AppConfig*/@Beanpublic AppConfig appConfig() {return new AppConfig();}
}

以上例子beanA不会被注入到Spring容器中。如果你需要AppConfig也被作为一个配置类来解析,可以使用@Import注解。

@Import(AppConfig.class)
@Configuration
public class MainConfig {}

这么写beanA会被注入到Spring容器中。

@Import

@Import注解主要作用用于导入一个配置类,不过呢,它导入的类分为三种情况。

  • 导入的类实现了ImportSelector接口,导入的类本身不会被注册到容器,实际注册的类为selectImports方法返回的类,注意返回的类也会按照这3种情况递归处理。
  • 导入的类实现了ImportBeanDefinitionRegistrar接口,导入的类本身不会被注册到容器,实际注册的类为registerBeanDefinitions方法中收到注册的类。
  • 除上述以外情况,导入的类将会被注册到容器中,并且会作为一个配置类继续解析,从而注册更多的bean到容器中(导入的类本身可以不用@Configuration进行注解)。

例子:

@Import({A.class, B.class})
@Configuration
public class AppConfig {}/*** 不在Spring Boot包扫描中,通过@Import注解导入*/
@Configuration
public class A {}public class B implements ImportSelector {@Override  public String[] selectImports(AnnotationMetadata importingClassMetadata) {  return new String[] {C.class.getName()};  }
}/*** 不在Spring Boot包扫描中,通过B的selectImports方法导入*/
@Configuration
public class C {}

在上述例子中,容器实际只注册了AppConfig、A、C。因为B是一个ImportSelector实例,不会被注册到容器中,不过B通过selectImports方法把C注册进来了。

ObjectProvider

  • ObjectProvider在注入时即使没有对应的bean,也不会报错,同样也可搭配@Qualifier注解注入指定名字的bean
  • getIfAvailable方法在有多个候选bean时会抛出NoUniqueBeanDefinitionException异常
  • getIfUnique方法在有多个候选bean时会返回null
http://www.jsqmd.com/news/535276/

相关文章:

  • 意法半导体:华虹40nm代工生产的STM32 MCU开启交付
  • IPTV抓包工具合集:Wireshark、parse_cap_channels_v2、IPTV全能工具箱
  • Bespoke Curator:解锁多模型AI协作的3大核心优势与实战指南
  • vue甘特图vxe-gantt自定义任务视图单元格的背景颜色
  • 20252916 2025-2026-2 《网络攻防实践》第3周作业
  • HunyuanImage-3.0-Instruct:8步玩转AI创意绘图
  • 树莓派4B实战:用systemd守护你的Python爬虫(附日志配置指南)
  • Visual Studio 2019下载地址
  • 阿里悟空 vs 腾讯龙虾:大厂 AI 自动化对决,普通人该怎么选?
  • VPI联合Matlab相干光通信仿真:发射端I/Q信号生成与VPI接口实战
  • LaTeX多行大括号公式速成指南:5分钟搞定不等式排版(附常见错误排查)
  • SpringBoot+Vue 校园健康驿站管理系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • 一文吃透AI智能体(Agent):从基础到核心,AI Agent大从概念到实战
  • 基于决策树手写数字识别 matlab实现 包含定位、分割(5*5)、二值化、主成分分析法 交叉...
  • 车载诊断架构 --- GB/T 18344-2025 规范探析
  • foobox-cn深度解析:foobar2000高级定制实战指南
  • IOPaint:AI图像修复的革命性突破,让专业级图片编辑触手可及
  • 从ADS原理图到PCB:一个射频功放版图设计的完整避坑指南(含Rogers板材参数设置)
  • EBioMedicine(IF=10.8)英国伦敦国王学院等团队:融合CT深度学习、CT放射组学与外周血免疫特征在症状患者队列中诊断肺癌的研究
  • 实战:利用‘语义锚定’技术,防止竞品通过 AI 生成的内容覆盖你的核心词条
  • 手把手教你用uniapp快速开发MES移动端(支持Android/iOS/小程序)
  • 【2025最新】基于SpringBoot+Vue的小型企业客户关系管理系统管理系统源码+MyBatis+MySQL
  • 如何3倍提升代码分析效率?这款工具让复杂项目一目了然
  • 从图表示学习到影响力优化:DeepIM框架的端到端革新之路
  • 别等出事才后悔!科研狗的血泪教训:盘点实验室那些“看似无害”的高危操作
  • 开源工具维护终止:微信云备份工具cloudbak风险应对指南
  • Kimi/豆包/DeepSeek生成的论文怎么降AI率?不同AI工具降AIGC策略详解
  • 用Pyecharts玩转动态图表:Flask整合3种数据源实战教程(CSV/MySQL/Linux集群)
  • 【紧急预警】2024Q3起NVIDIA驱动更新将导致PyTorch 2.3+大模型部署失效!硬件兼容性避坑清单(含CUDA 12.4认证设备表)
  • 手把手教你用ZYNQ PS端操作SD卡:基于Vivado 2019.1的实战记录