通常对于web项目使用的是ClassPathXmlApplicationContext作为容器,查看源码也以ClassPathXmlApplicationContext为例解读。Ioc,aop作为Spring的核心,而ioc是aop的基础,在bean生成期间做增强。在与mybatis做集成时,也是依赖于ioc,因而ioc的重要性不言而喻。
在ClassPathXmlApplicationContext的全参构造方法ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)中会调用refresh()方法,而这个方法就是Spring容器启动的起点。
进入方法可以看到同步代码块中定义了12个方法,以及如果容器启动失败用于重置容器的方法。
- prepareRefresh(); //准备阶段
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //获取beanfactory并且加载Bean到容器中(包括以xml文件配置的以及通过componentscan扫描到的Bean,此时的bean并没有初始化)。仅仅还是GenericBeanDefinition,后续的各种后置处理器还会对这些Bean做各种处理。
- prepareBeanFactory(beanFactory); //设置需要被忽略,被依赖的Bean,其中还会引入系统换进变量
- postProcessBeanFactory(beanFactory); //空方法
- invokeBeanFactoryPostProcessors(beanFactory);//对后置处理进行排序,priorityorder order,nonorder
- registerBeanPostProcessors(beanFactory); //根据优先级注册后置处理器
- initMessageSource(); //初始化标签国际化
- initApplicationEventMulticaster(); //初始化事件分发
- onRefresh(); //空方法
- 10.registerListeners();
- finishBeanFactoryInitialization(beanFactory); //完成bean的实例化和初始化,Autowired,Aop代理增强,Mybatis的接口代理,事务管理器都是在这里完成
- 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几乎都是原样返回,