参考博文: https://blog.csdn.net/f641385712/article/details/88651128

一 接口规范

从宏观上看,AutowireCapableBeanFactory提供了如下能力:

1 为已经实例化的对象装配属性,这些属性对象都是Spring管理的;

2 实例化一个Bean,并自动装配,这些被装配的属性对象都是Spring管理的,但是实例化的Bean可以不被Spring管理(这点特别重要)。所以这个接口提供功能就是自动装配bean相关的

(自动装配的原对象可以不在Spring的IOC容器里,但是需要被依赖注入的成员,就必须是Spring容器管辖的Bean)
 此接口主要是针对框架之外,没有向Spring托管Bean的应用。通过暴露此功能,Spring框架之外的程序,也能具有自动装配的能力(此接口赋予它的)。

可以使用这个接口集成其它框架。捆绑并填充(注入)并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用
 一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,

但是提供了getAutowireCapableBeanFactory()方法允许你拿这个工具去做你需要的事。

接口定义:

  1. public interface AutowireCapableBeanFactory01 extends BeanFactory {
  2. /**
  3. * 表明工厂没有自动装配的Bean
  4. */
  5. int AUTOWIRE_NO = 0;
  6.  
  7. /**
  8. * 表明根据名称自动装配
  9. */
  10. int AUTOWIRE_BY_NAME = 1;
  11.  
  12. /**
  13. * 表明根据类型自动装配
  14. */
  15. int AUTOWIRE_BY_TYPE = 2;
  16.  
  17. /**
  18. * 表明根据构造方法快速装配
  19. */
  20. int AUTOWIRE_CONSTRUCTOR = 3;
  21.  
  22. @Deprecated
  23. // 表明通过Bean的class的内部来自动装配 Spring3.0被弃用。
  24. int AUTOWIRE_AUTODETECT = 4;
  25.  
  26. String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
  27.  
  28. /**
  29. * 创建一个指定class的实例
  30. */
  31. <T> T createBean(Class<T> beanClass) throws BeansException;
  32.  
  33. /**
  34. * 通过调用给定Bean的after-instantiation及post-processing接口,对bean进行配置
  35. */
  36. void autowireBean(Object existingBean) throws BeansException;
  37.  
  38. /**
  39. * 自动装配属性,填充属性值,使用诸如setBeanName,setBeanFactory这样的工厂回调填充属性,最好还要调用post processor
  40. */
  41. Object configureBean(Object existingBean, String beanName) throws BeansException;
  42.  
  43. /**
  44. * 创建一个指定class的实例,通过参数可以指定其自动装配模式(by-name or by-type).
  45. */
  46. Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
  47.  
  48. /**
  49. * 通过指定的自动装配策略来初始化一个Bean
  50. */
  51. Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
  52.  
  53. /**
  54. * 通过指定的自动装配方式来对给定的Bean进行自动装配
  55. */
  56. void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
  57. throws BeansException;
  58.  
  59. /**
  60. * 将参数中指定了那么的Bean,注入给定实例当中
  61. */
  62. void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
  63.  
  64. /**
  65. * 初始化参数中指定的Bean,调用任何其注册的回调函数如setBeanName、setBeanFactory等。
  66. */
  67. Object initializeBean(Object existingBean, String beanName) throws BeansException;
  68.  
  69. /**
  70. * 调用参数中指定Bean的postProcessBeforeInitialization方法
  71. */
  72. Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
  73. throws BeansException;
  74.  
  75. /**
  76. * 调用参数中指定Bean的postProcessAfterInitialization方法
  77. */
  78. Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  79. throws BeansException;
  80.  
  81. /**
  82. * 销毁参数中指定的Bean,同时调用此Bean上的DisposableBean和DestructionAwareBeanPostProcessors方法
  83. */
  84. void destroyBean(Object existingBean);
  85.  
  86. /**
  87. * 查找唯一符合指定类的实例,如果有,则返回实例的名字和实例本身
  88. * 底层依赖于:BeanFactory中的getBean(Class)方法
  89. */
  90. <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
  91.  
  92. /**
  93. * 解析出在Factory中与指定Bean有指定依赖关系的Bean(@Autowired依赖注入的核心方法)
  94. */
  95. Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
  96.  
  97. @Nullable
  98. Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
  99.  
  100. @Nullable
  101. Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
  102. @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
  103. }

二 实际应用

准备一个外部类,即不被spring容器管理:

  1. public class Person {
  2.  
  3. //不使用@Autowired
  4. private User user;
  5.  
  6. public User getUser() {
  7. return user;
  8. }
  9.  
  10. public void setUser(User user) {
  11. this.user = user;
  12. }
  13. }

spring管理的User bean进行实例化,这里以spring-bean.xml为例:

利用AutowireCapableBeanFactory创建Bean:

  1. public class BeanTest{
  2. @Test
  3. public void beanTest(){
  4. ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
  5. //ApplicationContext没有实现接口,但是可以通过方法直接获取使用
  6. AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
  7. // autowireCapableBeanFactory创建Bean实例,执行多次就创建多个
  8. Person person = (Person) autowireCapableBeanFactory.createBean(Person.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
  9. //没有@Autowired注解也直接给注入了
  10. System.out.println("获取自动注入的属性:"+person.getUser());
  11. //异常: No qualifying bean of type 'com.hou.spring.Person' available
  12. Person bean = applicationContext.getBean(Person.class);//没有交给spring容器管理
  13. System.out.println(bean);
  14. }
  15. }

执行结果:

不使用接口测试:

三 源码分析

主要从createBean方法进行分析:

这个接口调用的方法是在AbstractAutowireCapableBeanFactory抽象类中实现的:

  1. @Override
  2. public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
  3. // Use non-singleton bean definition, to avoid registering bean as dependent bean.
  4. RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
  5. //这里设置为原型,而不是单例,所以调用多次会生成多个对象
  6. bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  7. return createBean(beanClass.getName(), bd, null);
  8. }

然后就是return里面调用的createBean方法,这个是AbstractAutowireCapableBeanFactory类的父类AbstractBeanFactory定义的抽象方法:

AbstractAutowireCapableBeanFactory类中实现了这个抽象方法,这个方法很单纯:创建一个实例,然后初始化他(给属性们赋值),然后return出去即可:

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4.  
  5. if (logger.isTraceEnabled()) {
  6. logger.trace("Creating instance of bean '" + beanName + "'");
  7. }
  8. RootBeanDefinition mbdToUse = mbd;
  9.  
  10. // Make sure bean class is actually resolved at this point, and
  11. // clone the bean definition in case of a dynamically resolved Class
  12. // which cannot be stored in the shared merged bean definition.
  13. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  14. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  15. mbdToUse = new RootBeanDefinition(mbd);
  16. mbdToUse.setBeanClass(resolvedClass);
  17. }
  18.  
  19. try {
  20. mbdToUse.prepareMethodOverrides();
  21. }
  22. catch (BeanDefinitionValidationException ex) {
  23. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  24. beanName, "Validation of method overrides failed", ex);
  25. }
  26.  
  27. try {
  28. //若BeanPostProcessors 产生了一个代理对象,就不需要我去创建了,就不继续往下走了(AOP都走这里)
  29. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  30. if (bean != null) {
  31. return bean;
  32. }
  33. }
  34. catch (Throwable ex) {
  35. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  36. "BeanPostProcessor before instantiation of bean failed", ex);
  37. }
  38.  
  39. try {
  40. //本类的一个protected方法,专门用于处理创建Bean的过程(包括属性赋值之类的)
  41. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  42. if (logger.isTraceEnabled()) {
  43. logger.trace("Finished creating instance of bean '" + beanName + "'");
  44. }
  45. return beanInstance;
  46. }
  47. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  48. throw ex;
  49. }
  50. catch (Throwable ex) {
  51. throw new BeanCreationException(
  52. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  53. }
  54. }

再看本类的doCreateBean方法,主要有三个核心步骤三个步骤:createBeanInstancepopulateBeaninitializeBean:

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2. throws BeanCreationException {
  3.  
  4. // Instantiate the bean.
  5. BeanWrapper instanceWrapper = null;
  6. if (mbd.isSingleton()) {
  7. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  8. }
  9. if (instanceWrapper == null) {
  10. //创建Bean实例,返回一个BeanWrapper,它也是本类的一个protected方法
  11. instanceWrapper = createBeanInstance(beanName, mbd, args);
  12. }
  13. final Object bean = instanceWrapper.getWrappedInstance();
  14. Class<?> beanType = instanceWrapper.getWrappedClass();
  15. if (beanType != NullBean.class) {
  16. mbd.resolvedTargetType = beanType;
  17. }
  18.  
  19. // 处理循环引用,现在若我们Bean不在容器里,肯定是不存在循环引用的(但是我依赖的Bean可能还没创建是真的,也是这里来处理的)
  20. synchronized (mbd.postProcessingLock) {
  21. if (!mbd.postProcessed) {
  22. try {
  23. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  24. }
  25. catch (Throwable ex) {
  26. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  27. "Post-processing of merged bean definition failed", ex);
  28. }
  29. mbd.postProcessed = true;
  30. }
  31. }
  32.  
  33. // Eagerly cache singletons to be able to resolve circular references
  34. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  35. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  36. isSingletonCurrentlyInCreation(beanName));
  37. if (earlySingletonExposure) {
  38. if (logger.isTraceEnabled()) {
  39. logger.trace("Eagerly caching bean '" + beanName +
  40. "' to allow for resolving potential circular references");
  41. }
  42. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  43. }
  44.  
  45. Object exposedObject = bean;
  46. try {
  47. //// 给Bean实例的各个属性进行赋值
  48. populateBean(beanName, mbd, instanceWrapper);
  49. //初始化Bean 执行一些初始化方法init @PostContruct方法等等
  50. exposedObject = initializeBean(beanName, exposedObject, mbd);
  51. }

其他具体细节以后其他博文专门记录笔记

springIOC源码接口分析(八):AutowireCapableBeanFactory的更多相关文章

  1. springIOC源码接口分析(三):ApplicationContext

    一 新增方法 主要都是获取容器基本信息的一些接口,比如获取名称,id和启动时间戳,获取AutowireCapableBeanFactory等接口 二 继承接口 ApplicationContext继承 ...

  2. springIOC源码接口分析(九):Environment

    先贴一下接口继承关系图,spring容器启动的时候会初始化环境,所以此接口相关接口非常有必要进行了解: 一 PropertyResolver接口 Environment继承了该接口,PropertyR ...

  3. springIOC源码接口分析(十一):ConfigurableApplicationContext

    一 实现接口 关系图: ConfigurableApplicationContext接口实现了三个接口,ApplicationContext, Lifecycle, Closeable, Applic ...

  4. springIOC源码接口分析(七):ApplicationEventPublisher

    一 定义方法 此接口主要是封装事件发布功能的接口,定义了两个方法: /** * 通知应用所有已注册且匹配的监听器此ApplicationEvent */ default void publishEve ...

  5. springIOC源码接口分析(六):ResourceLoader

    参考博客: https://www.cnblogs.com/jixp/articles/10702486.html 一 定义方法 Spring提供了ResourceLoader接口用于实现不同的Res ...

  6. springIOC源码接口分析(五):ListableBeanFactory

    一 继承关系 该接口是对BeanFactory的扩展,允许预加载bean定义的BeanFactory可以实现此接口 其目的在于使实现它的BeanFactory能够枚举所有的Bean 该接口不支持分层结 ...

  7. springIOC源码接口分析(四):MessageSource

    一 定义方法 MessageSource接口用于支持信息的国际化和包含参数的信息的替换 这个接口定义了三个方法: public interface MessageSource { /** * 解析co ...

  8. springIOC源码接口分析(二):ConfigurableBeanFactory

    一 继承功能 1 SingletonBeanRegistry接口 此接口是针对Spring中的单例Bean设计的.提供了统一访问单例Bean的功能,类中定义了以下方法: 2 HierarchicalB ...

  9. springIOC源码接口分析(一):BeanFactory

    一 应用场景 BeanFactory接口定义了IOC容器的最基本功能,提供了容器应该具有的功能规范,所有的容器都应该实现这个接口 BeanFactory设计了getBean方法用来获取容器中的Bean ...

随机推荐

  1. CodeTypeDeclaration,CodeMemberProperty动态生成代码

    由于是CodeDom些列,所以先介绍几个CodeDom表达式: :CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数: pub ...

  2. CPP 设计模式学习

    源地址 https://www.ev0l.art/index.php/archives/20/ 备忘录模式 在一个类内部记录另一个类的快照状态的模式.可以再合适的时候跳回复用 设计备忘录的三大步骤: ...

  3. 选题Scrum立会报告+燃尽图 02

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8680 组长:杨天宇 组员:魏新,罗杨美慧,王歆瑶,徐丽君 组名:组长 第 ...

  4. 【题解】P4137 Rmq Problem(莫队)

    [题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的 ...

  5. $Poj2228$/洛谷$SP283\ Naptime$ 环形$DP$

    Luogu 一定要记得初始化为-inf!!! Description 在某个星球上,一天由N小时构成.我们称0-1点为第一个小时,1-2点为第二个小时,以此类推.在第i个小时睡觉能恢复Ui点体力.在这 ...

  6. java poi ppt 接口的基本操作

    依赖 在 pom.xml中增加以下依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId& ...

  7. 集合排序Comparable和Comparator有什么区别?

    Comparable和Comparator兄弟俩长得是真像.但是,需要注意下,使用中它们还是有不少区别的.下面,就一探究竟吧. 一.Comparator 做过集合排序的童鞋应该知道,可以使用Colle ...

  8. Java网络编程——UDP聊天程序

    UDP简介 UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据报.在OSI模型中,UDP位于第四层--传输层,处于IP协议额上一层.UDP有不提供数据报分组.组装以及不能对数据报排序 ...

  9. 1038 统计同成绩学生 (20 分)C语言

    题目描述 本题要求读入N名学生的成绩,将获得某一给定分数的学生人数输出. 输入描述: 输入在第1行给出不超过105的正整数N,即学生总人数.随后1行给出N名学生的百分制整数成绩,中间以空格分隔.最后1 ...

  10. 1045 快速排序 (25 分)C语言

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的 N 个互不相同的正整数的排列,请问 ...