Spring中创建对象的方式整理

在没有使用Spring时,开发者创建对象一般都是使用new/反射创建对象;Spring出来后简化了开发方式,它提供了一个IoC容器的实现,用于帮助开发者以依赖注入的方式管理对象之间的依赖关系,从而将开发者创建对象的所有权转移到IoC容器上,这使得Spring易于整合第三方模块,因此Spring更是一个分层的框架;

 

对于Spring创建对象的方式创建整理如下:#

方式一:自定义BeanPostProcessor,生成代理对象#

如实现InstantiationAwareBeanPostProcessor接口,其中InstantiationAwareBeanPostProcessor是一个BeanPostProcessor,它可用于处理bean实例创建前后的回调;

 

测试如下:

  

 

  

 

注:

MethodProxy#invokeSuper是退出当前interceptor的处理,进入下一个callback处理;

MethodProxy#invoke则会继续回调该方法,如果传递给invoke的obj参数出错容易造成递归调用;

 

方式二:通过反射创建#

AbstractAutowireCapableBeanFactory#doCreateBean为真正创建bean的逻辑,该方法是最复杂的,包含了调用构造函数,给bean的属性赋值,调用bean的初始化操作以及生成代理对象;

该方法会调用AbstractAutowireCapableBeanFactory#createBeanInstance实例化对象,如下图;

 

AbstractAutowireCapableBeanFactory#createBeanInstance#

判断Bean定义信息中的resolvedConstructorOrFactoryMethod是否缓存,因为需要根据参数确认到底使用哪个构造器,该过程比较消耗性能,所以采用缓存机制;

 

通过bean的后置处理器进行获取合适的构造器对象,有且只有一个有参构造或有且只有一个@Autowired注解构造;

 

创建对象方式#

AbstractAutowireCapableBeanFactory#createBeanInstance根据@Autowried自动注入/调用无参构造器创建,进行相应的处理;

  • instantiateBean 调用无参数的构造器进行创建对象;
  • autowireConstructor @Autowired自动注入,调用构造器注入;

 

方式三:通过FactoryBean创建对象#

AbstractBeanFactory#getObjectForBeanInstance

如果有实现了FactoryBean接口的实例,则从FactoryBean中获取实例;

 

测试如下:

  

  

  

 

方式四:通过设置BeanDefinition属性Supplier创建对象#

AbstractAutowireCapableBeanFactory#createBeanInstance

获取bean的supplier; 

 

AbstractAutowireCapableBeanFactory#obtainFromSupplier

通过Suupplier#get方法获取实例,此时获取实例不是使用反射; 

 

测试如下:

  

  

 

方式五:通过设置BeanDefinition属性factoryMethod创建对象#

AbstractAutowireCapableBeanFactory#createBeanInstance

createBeanInstance是实例化对象的过程,如果beanDefinition设置了factoryMethod,则从设置的factoryMethod实例化,而supplier属性的优先级高于factoryMethod即beanDefinition同时存在supplier和factoryMethod属性时,优先执行supplier的实例化逻辑

 

mbd的factoryMethodNameBeanDefiniton加载时赋值的,如下: 

ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod

 

factoryMethod使用方式:往beanDefinition设置factoryMethod所属类的beanNamefactoryMethodName的属性;

使用factoryMethod实例化对象的解析逻辑:ConstructorResolver#instantiateUsingFactoryMethod

 

SimpleInstantiationStrategy最终通过对factoryBean反射调用factoryMethod;

 

 

测试如下:

beanDefinition只有factoryMethod属性#

  

 
调用无参的factoryMethod

  

 

调用有参factoryMethod

  

 

beanDefinition有factoryMethod属性和supplier属性#

 

此时优先执行supplier逻辑;

 

Spring创建对象方式的整理图#

 

 

Spring实例化策略整理#

 

posted @   街头卖艺的肖邦  阅读(1405)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2021-01-10 关于MySQL INT类型长度的疑惑
点击右上角即可分享
微信分享提示
主题色彩