Spring源码学习第十天==>浅谈Bean的几种创建方式

前言:在Spring的IOC容器中提供了丰富多样的创建Bean的方式,先上图。

1.通过FactoryBean直接或者间接得到的Bean对象。(这一部分的知识在Spring学习第八天中的FactoryBean小节进行过解释和图示)

    目的:通过FactoryBean的方式可以规避创建Bean时复杂的流程(实例化,bpp-begin,bpp-after.....)

    结果:直接:通过context.getBean(“&FactoryBeanName”):通过这种方式可以获取到FactoryBean对象

               间接:通过context.getBean("FactoryBeanName"):可以得到FactoryBean通过getObject()方法得到的对象

2.通过在xml中为Bean配置< lookup-metyhod/>  <replace-method/>来获取对象

    目的:通过这样的方式可以在原型模式下引用一个原型模式的bean

             1.如果通过常规的方式(单例的Bean对象通过属性注入一个原型模式的Bean对象,会发现每次得到的原型模式的属性都是同一个,没有得到多例的效果)

             2.而添加<lookup-method/><replace-method>标签是通过拦截器的方式每次需要的时候都去创建最新的对象,而不会把原型对象缓存起来。

     结果:通过getBean()得到对象的类类型是一致的,在标签中设置的方法的返回值类类型也是一致的。但是是否单例/原型,需要根据配置中规则来决定

3.通过以resolveBeforeInstantiation为入口的方式创建Bean

     目的:这种方式通过实现InstantiationAwareBeanPostProcessor接口可以选择在Bean的实例化前/后,初始化前/后,属性设置等进行丰富多样的设置

4.通过Supplier的方式创建Bean

     目的:本质上还是创建Bean,在创建Bean的过程中可以进行丰富Bean信息的操作。

     实现:创建一个实现BeanFactoryPostProcessor接口的子类,实现postProcessorBeanFactory。关于BFPP的内容

 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 获取到BeanName:user 的Bean定义信息
        BeanDefinition user = beanFactory.getBeanDefinition("user");
        // 知识点:
        // 1.GenericBeanDefinition是BeanDefinition的子类
        // 2.GenericBeanDefinition有一个继承自AbstractBeanDefinition的成员属性【类型为Supplier】
        GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) user;
        // 3.Supplier是一个函数式接口(里面有一个唯一方法Get),我们通过Lambda表达式传入一个创建Bean的方法
        genericBeanDefinition.setInstanceSupplier(CreateSupplier::createUser);
        genericBeanDefinition.setBeanClass(User.class);
    }

       获得结果处:如以下代码段

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		/
         .....
        / 
		// 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
        /
         .....
        /

	}

5.通过静态/实例工厂创建Bean

     目的:通过静态/实例工厂创建Bean实例,也是通过我们常用的<bean/>标签中的factory-bean,factory-method属性来实现

     粗略的流程介绍:

                              1.判断是静态工厂还是实例工厂,如果是静态工厂的话标志位置为true

                              2.获取构造函数参数值数组

                              3.获取所有的构造方法集合,并按照参数个数降序排序

                                 3.1意义:可以减少不必要的判断,比如说参数个数为3,那么参数个数<=2的构造方法就不需要取执行判断了

                              4.选择合适的构造方法进行实例化

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值