随心记

被@Bean标注的方法是怎么被注册为一个bean的

在 Spring 框架中,被@Bean标注的方法会通过以下流程被注册为容器中的 bean:

1. 配置类解析阶段

  • ConfigurationClassPostProcessor:Spring 的BeanFactoryPostProcessor会扫描所有带有@Configuration@Component注解的类
  • 方法解析:识别这些类中所有被@Bean标注的方法,并提取元数据(如方法名、返回类型、作用域等)

2. BeanDefinition 注册阶段

  • BeanDefinition:为每个@Bean方法创建一个RootBeanDefinitionConfigurationClassBeanDefinition
  • 注册到容器:这些BeanDefinition会被注册到BeanFactorybeanDefinitionMap中,键为 bean 名称(默认是方法名)

3. 实例化与依赖注入阶段

  • 延迟实例化:大多数 bean 是在首次被依赖时才会实例化(单例 bean 在容器启动时实例化)
  • 方法调用:容器通过反射调用@Bean方法,获取返回的对象实例
  • 依赖处理:如果方法有参数,Spring 会自动解析并注入这些依赖

4. 配置类代理机制(仅针对@Configuration类)

  • CGLIB 代理@Configuration类会被 CGLIB 增强,确保方法调用时返回容器中的单例 bean
  • 拦截逻辑:当代理对象调用@Bean方法时,会先检查容器中是否已有该 bean,而非直接执行方法
  • 核心机制总结
  • 元数据解析:Spring 通过 ASM 技术解析类的字节码,提取@Bean方法信息
  • 生命周期管理@Bean方法返回的对象由 Spring 容器管理,包括初始化、依赖注入和销毁
  • 代理增强@Configuration类的代理确保方法调用时返回容器中的单例 bean,而非创建新实例
  • 条件注册:结合@Conditional等注解,可以根据条件决定是否注册该 bean

在bean()里面加名字是为啥

默认情况下,bean 名称是方法名。通过name属性可以覆盖这一行为,使名称更具描述性或符合特定规范。

2. 解决名称冲突

当多个@Bean方法返回相同类型的 bean 时,必须通过名称区分它们。

@Configuration
public class DataSourceConfig {
    @Bean(name = "primaryDataSource")
    public DataSource mysqlDataSource() { ... }

    @Bean(name = "secondaryDataSource")
    public DataSource oracleDataSource() { ... }
}

此时,可通过名称注入特定的 bean:

@Autowired
@Qualifier("primaryDataSource")  // 指定名称
private DataSource dataSource;

在 Spring 框架中,@Autowired结合@Qualifier注入的是方法返回的对象实例,而非配置类本身。这是因为 Spring 的依赖注入系统关注的是bean 实例,而非定义 bean 的方法或类。

ctrl+h 可以对源码进行查看

博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇