spring-core-4-35 | 注册Spring Bean:如何将BeanDefinition注册到IoC容器?

本文深入探讨Spring框架中Bean注册的不同方式,包括XML配置、Java注解(@Bean、@Component、@Import)、Java API(BeanDefinitionRegistry、SingletonBeanRegistry)等,并通过具体代码示例进行演示。

注册Spring Bean

BeanDefinition 注册

XML 配置元信息

• <bean name=”…” … />
还有properties文件的方式, 后面予以介绍
因为XML的方式之前 讲了太多, 这里就不展开了

Java 注解配置元信息

• @Bean

• @Component

• @Import

Java API 配置元信息

也是最底层的方式

• 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)

• 非命名方式:

BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,Be

anDefinitionRegistry)

• 配置类方式:AnnotatedBeanDefinitionReader#register(Class…)

外部单例对象注册

Java API 配置元信息

• SingletonBeanRegistry#registerSingleton

代码示例

这里只介绍怎么使用, 后面在介绍原理
spring-core项目
搜索 35 | 注册Spring Bean
AnnotationBeanDefinitionDemo.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.geekbang.thinking.in.spring.bean.definition;

import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;

/**
 * 35 | 注册Spring Bean:如何将BeanDefinition注册到IoC容器?
 * <p>
 * 注解 BeanDefinition 示例
 * 1. 通过 @Bean 方式定义
 * 2. 通过 @Component 方式
 * 3. 通过 @Import 来进行导入
 * @Component和@Import有一个重复导入的情况
 * 上面这三种方式如果导入的是同一个对象, id就会一致, 是不会出现重复的, 这是spring很严谨的地方
 * 4. 通过 BeanDefinition 注册 API 实现
 * 1.命名 Bean 的注册方式
 * 2. 非命名 Bean 的注册方法
 * 两种方式如果bean的id不同, 也就会有两个不同的对象会注册
 * <p>
 * • BeanDefinition 注册
 *      • XML 配置元信息
 *          • <bean name=”...” ... />
 *      • Java 注解配置元信息
 *          • @Bean
 *          • @Component
 *          • @Import
 *      • Java API 配置元信息
 *          • 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
 *          • 非命名方式:
 *          BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDefinitionRegistry)
 *          • 配置类方式:AnnotatedBeanDefinitionReader#register(Class...)
 * • 外部单例对象注册
 *      • Java API 配置元信息
 *          • SingletonBeanRegistry#registerSingleton   见 SingletonBeanRegistrationDemo.java
 *
 * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
 * @since
 */
// 3. 通过 @Import 来进行导入
@Import(AnnotationBeanDefinitionDemo.Config.class)
public class AnnotationBeanDefinitionDemo {

    public static void main(String[] args) {
        // 创建 BeanFactory 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 这里Config类后来换成注解@Import来进行导入
        //applicationContext.register(Config.class);
        // 注册 Configuration Class(配置类)
        applicationContext.register(AnnotationBeanDefinitionDemo.class);

        // 4. 通过 BeanDefinition 注册 API 实现
        // 4.1. 命名 Bean 的注册方式
        registerUserBeanDefinition(applicationContext, "mercyblitz-user");
        // 4.2. 非命名 Bean 的注册方法
        registerUserBeanDefinition(applicationContext);

        // 启动 Spring 应用上下文
        applicationContext.refresh();
        // 按照类型依赖查找
        // 这里不会打印别名, 因为别名不是一个单独的bean
        System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class));
        System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class));
        // 显示地关闭 Spring 应用上下文
        applicationContext.close();
    }

    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
        beanDefinitionBuilder
                .addPropertyValue("id", 1L)
                .addPropertyValue("name", "小马哥");

        // 判断如果 beanName 参数存在时
        if (StringUtils.hasText(beanName)) {
            // 注册 BeanDefinition
            registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        } else {
            // 非命名 Bean 注册方法
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
        }
    }

    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry) {
        registerUserBeanDefinition(registry, null);
    }

    // 2. 通过 @Component 方式
    @Component // 定义当前类作为 Spring Bean(组件)
    public static class Config {

        // 1. 通过 @Bean 方式定义

        /**
         * 通过 Java 注解的方式,定义了一个 Bean
         * name有多个时, 第一个是bean的name, 后面的都是alias别名
         */
        @Bean(name = {"user", "xiaomage-user"})
        public User user() {
            User user = new User();
            user.setId(1L);
            user.setName("小马哥");
            return user;
        }
    }


}

源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到点击 控制台粘贴代码运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值