Spring IOC与自动注入Autowired

通常对于web项目使用的是ClassPathXmlApplicationContext作为容器,查看源码也以ClassPathXmlApplicationContext为例解读。Ioc,aop作为Spring的核心,而ioc是aop的基础,在bean生成期间做增强。在与mybatis做集成时,也是依赖于ioc,因而ioc的重要性不言而喻。

在ClassPathXmlApplicationContext的全参构造方法ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)中会调用refresh()方法,而这个方法就是Spring容器启动的起点。
进入方法可以看到同步代码块中定义了12个方法,以及如果容器启动失败用于重置容器的方法。

  1. prepareRefresh(); //准备阶段
  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //获取beanfactory并且加载Bean到容器中(包括以xml文件配置的以及通过componentscan扫描到的Bean,此时的bean并没有初始化)。仅仅还是GenericBeanDefinition,后续的各种后置处理器还会对这些Bean做各种处理。
  3. prepareBeanFactory(beanFactory); //设置需要被忽略,被依赖的Bean,其中还会引入系统换进变量
  4. postProcessBeanFactory(beanFactory); //空方法
  5. invokeBeanFactoryPostProcessors(beanFactory);//对后置处理进行排序,priorityorder order,nonorder
  6. registerBeanPostProcessors(beanFactory); //根据优先级注册后置处理器
  7. initMessageSource(); //初始化标签国际化
  8. initApplicationEventMulticaster(); //初始化事件分发
  9. onRefresh(); //空方法
  10. 10.registerListeners();
  11. finishBeanFactoryInitialization(beanFactory); //完成bean的实例化和初始化,Autowired,Aop代理增强,Mybatis的接口代理,事务管理器都是在这里完成
  12. finishRefresh();

追踪方法栈 finishBeanFactoryInitialization ->preInstantiateSingletons -> getBean -> doGetBean -> createBean -> doCreateBean ,进入之后可以看到重要的几个方法

instanceWrapper = createBeanInstance(beanName, mbd, args); 创建Bean的包装类
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);后置处理器生效,
      包括Autowired相关的后置处理器,Aop增强,事务等
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd); //初始化,有需要增强的
Bean会在这个方法进行

依赖图


自动注入Autowired
在applyMergedBeanDefinitionPostProcessors方法中会遍历所有的Beanpostprocess,从中找出实现了MergedBeanDefinitionPostProcessor的后置处理器并使之生效。与自动注入相关的是AutowiredAnnotationBeanPostProcessor,该后置处理器是PriorityOrdered的实例,会在后置处理器的第一梯队对Bean的实例化进行修饰。
调用postProcessProperties:
–> postProcessMergedBeanDefinition
–> findAutowiringMetadata ;//找到注入点
–> checkConfigMembers //将找到的注入点,并将值添加到Beandefinition的 externallyManagedConfigMembers字段中,给后续注入使用


在populateBean方法中会遍历所有的Beanpostprocess,从中找出实现了InstantiationAwareBeanPostProcessor的后置处理器并使之生效。与自动注入相关的是AutowiredAnnotationBeanPostProcessor:
调用postProcessProperties:
1.找到需要被注入的字段
–> findAutowiringMetadata(beanName, bean.getClass(), pvs)
–> buildAutowiringMetadata(clazz);//构建元数据并添加到后置处理器的map中,给下一步注入使用
–>findAutowiredAnnotation ;找出带有@Value或@Autowired或@Inject的字段/方法,并封装成injectmetadata
2.完成注入 --> metadata.inject(bean, beanName, pvs)
—>element.inject --> beanFactory.resolveDependency -->doResolveDependency -->resolveCandidate --> beanFactory.getBean(beanName) ;//解决依赖,保证被依赖的Bean实例化初始化,类似于递归解决依赖。
采用反射设置要注入的值:
ReflectionUtils.makeAccessible(field);
field.set(bean, value);


在populateBean方法中主要调用两个方法最beandefinition进行前置和后置增强
–> applyBeanPostProcessorsBeforeInitialization:
遍历所有后置处理器并调用postProcessBeforeInitialization,对于普通Bean几乎都是原样返回,
–> applyBeanPostProcessorsAfterInitialization
遍历所有后置处理器并调用postProcessAfterInitialization,对于普通Bean几乎都是原样返回,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值