基于spring源码将对象以手动方式注册到spring容器

前言

Spring 中用BeanDefinition接口描述一个bean,描述对象的信息,依赖的信息,Spring容器中用ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap
存储beanName和BeanDefinition对象的映射关系【beanDefinitionMap 可参考DefaultListableBeanFactory】。
Spring在实例化一个bean,都是先从 beanDefinitionMap 中获取beanDefinition对象,进而构造出对应的bean。因此,我们手动注册bean的问题,就演化为如何往这个 beanDefinitionMap 放入我们要注册bean对应的 BeanDefinition 对象。
好的框架肯定有好的拓展性,Spring 提供了 BeanDefinitionRegistry 接口来操作底层beanFactory实现的beanDefinitionMap。
Spring5中的BeanDefinitionBuilder增加了一个新的genericBeanDefinition方法,签名如下:
public static BeanDefinitionBuilder genericBeanDefinition(
@Nullable Class beanClass, Supplier instanceSupplier)

实现思路

将自定义对象注入 ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap 中,需要三个方法来实现,方法的签名省略了,只是用于说明步骤:

  1. BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(); 获取到 beanDefinitionBuilder 对象;
  2. BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition(); 获取具体的beanDefinition对象;
  3. beanFactory.registerBeanDefinition(); 将beanDefinition对象注入到 beanDefinitionMap 中。

具体代码

下面用1个示例来说明,如何手动的将自定义对象注册到spring容器中。

  1. 创建两个对象,其中PersonDao和PersonManager是依赖关系,PersonManager是一个自建的类,而PersonDao对象已经交给spring管理了,目的是将PersonManager类交给spring管理。
    在这里插入图片描述
    在这里插入图片描述

  2. 将PersonManager对象交给spring管理

@Component
public class Test {

    @Autowired
    private ConfigurableApplicationContext context;

    /**
     * 初始化.
     */
    @PostConstruct
    public void init() {
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
            .genericBeanDefinition(PersonManager.class, () -> {
                PersonDao personDao = beanFactory.getBean(PersonDao.class);
                PersonManager personManager = new PersonManager();
                personManager.setPersonDao(personDao);
                return personManager;
            });
        BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder
            .getRawBeanDefinition();
        ((DefaultListableBeanFactory) beanFactory)
            .registerBeanDefinition("personManager2", personManagerBeanDefinition);
    }
}

BeanDefinitionBuilder.genericBeanDefinition()方法的第一个参数是personManager2的类型,是PersonManager类型,第二个参数是Supplier类型,返回PersonManager类型的对象,可以new一个PersonManager类型对象返回,在Supplier的重写方法中,创建对象,给对象的成员变量personDao赋值。这样对象和对象的依赖关系就生成了,最后把对象交给spring管理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值