小马哥讲Spring核心编程思想-spring bean 基础

前言

没有

一、BeanDefinition

是什么

BeanDefinition 是 Spring 中的一个核心概念,它用于描述一个 Bean 实例的属性和行为,并提供了创建和管理 Bean 实例的基础信息。

BeanDefinition 描述了一个 Bean 实例的基本信息,包括 Bean 的类型、属性、构造函数参数、初始化方法、销毁方法等。IOC 容器根据这些信息来创建和管理 Bean 实例,使得开发者无需手动创建和管理 Bean 实例,从而实现了控制反转。

元信息

如下图
在这里插入图片描述

BeanDefinition 构建

  • 通过 BeanDefinitionBuilder
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
  • 通过 AbstractBeanDefinition 以及派生类
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
// 设置 Bean 类型
genericBeanDefinition.setBeanClass(User.class);

二、spring bean的名称

每个 Bean 拥有一个或多个标识符(identifiers),这些标识符在 Bean 所在的容器必须是唯一的。通常,一个 Bean 仅有一个标识符,如果需要额外的,可考虑使用别名(Alias)来扩充。
在基于 XML 的配置元信息中,开发人员可用 id 或者 name 属性来规定 Bean 的 标识符。通常 Bean 的 标识符由字母组成,允许出现特殊字符。
Bean 的 id 或 name 属性并非必须制定,如果留空的话,容器会为 Bean 自动生成一个唯一的名称。
Bean 名称生成器(BeanNameGenerator)由 Spring Framework 2.0.3 引入,框架內建两种实现:DefaultBeanNameGenerator:默认通用 BeanNameGenerator 实现

三、spring bean的别名

将 Spring 容器中 “user” Bean 关联/建立别名 - “xz-user”

<alias name="user" alias="xz-user" />

然后取的时候就可以用 user 或 别名 xz-user 取了

// 启动 Spring 应用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/bean-definitions-context.xml");
// 通过别名 xiaomage-user 获取曾用名 user 的 bean
User user = beanFactory.getBean("user", User.class);
User xzUser = beanFactory.getBean("xz-user", User.class);
// 结果为 true
System.out.println("xz-user 是否与 user Bean 相同:" + (user == xzUser));

四、将 BeanDefinition 注册到 Ioc 容器

  1. XML方式
  2. Java注解方式(@Bean、@Component、@Import)
  3. Java API 配置元信息(命名方式、非命名方式、配置类方式)
public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder 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);
        }
        // 配置类方式
        // DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 基于 Java 注解的 AnnotatedBeanDefinitionReader 的实现
        // AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
        // 注册当前类(非 @Component class)
        // beanDefinitionReader.register(AnnotatedBeanDefinitionParsingDemo.class);
    }

五、实例化Spring Bean

这里不记录实现代码,因为一般不会去使用。

  • 常规方式
    1、通过构造器(配置元信息:XML、Java 注解和 Java API)
    2、通过静态工厂方法(配置元信息:XML和 Java API)
    3、通过 Bean 工厂方法(配置元信息:XML和 Java API)
    4、通过 FactoryBean(配置元信息:XML、Java 注解和 Java API)

  • 特殊方式
    1、通过 ServiceLoaderFactoryBean(配置元信息:XML、Java 注解和 Java API)
    2、通过 AutowireCapableBeanFactory#createBean(java.lang.Class, int, boolean)
    3、通过 BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)

六、Bean 初始化

作用:在你的bean在初始化时,会调用该方法

  • @PostConstruct 标注方法
  • 实现 InitializingBean 接口的 afterPropertierSet()方法
  • 自定义初始化方法
    1、XML 配置:<bean init-method=“init”… />
    2、Java 注解:@Bean(initMethod=“init”)
    3、Java APl: AbstractBeanDefinition#setinitMethodName(String)

如果三种方式都进行了配置,对应的执行顺序则为 @PostConstruct、afterPropertierSet()方法、自定义初始化方法

补充:
Bean 延迟初始化
实现方式:

  • XML 配置:<bean lazy-init=“true”… />
  • Java 注解:@Lazy(true)

和非延迟初始化的区别:延迟初始化是使用的时候才去创建,非延迟就是先准备好,用的时候直接用

七、Bean 销毁

作用:在bean销毁时,调用该方法
实现方式和 Bean 的初始化类似

  • @PreDestroy 标注方法
  • 实现 DisposableBean 接口的 destroy()方法
  • 自定义销毁方法
    1、XML 配置:<bean destroy=“destroy”… />
    2、Java 注解:@Bean(destroy=“destroy”)
    3、Java API:AbstractBeanDefinition#setDestroyMethodName(String)

八、回收 Spring Bean

只有关闭了 Spring 容器 才会回收 Spring Bean

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值