1.用于解析applicationcontext.xml 名称空间的解析器是哪里来的?
答:在容器fresh过程中的 obtainFreshBeanFactory 阶段会去加载xml配置文件中配置的Bean,而在此之前就是要通过名称空间拿到对应的名称空间解析器,这个过程交给 XmlBeanDefinitionReader去完成。它会创建名称空间解析器,在开始解析xml文件之前会通过类加载器去加载 META-INF/spring.handlers 文件中的以k-v 保存的命名空间和对应的解析器。
2. 命名空间解析器是什么时候注册到容器并实例化的?
答:在解析到xml的命名空间后根据命名空间的名字,从 handlerMappings 中以名称空间为key获取对应的解析器的名字,然后通过反射生成一个实例。接着初始化解析器。并把该命名空间相关的解析器都注入到xml文件解析器的parsers map中。 默认完成这个动作的解析器是一下类 DefaultNamespaceHandlerResolver.resolve(String namespaceUri) 中去完成实例化和初始化。
3.在标签解析过程中创建 CompositeComponentDefinition的意义是什么,为什么要这么做?
4:类似于mvc:annotation-driven 这种自定义标签,相关的嵌套组件是什么时候注册到容器的?
答:在找到了标签对应的解析器后,会调用解析器的parse方法,方法中会把标签关联的组件都注册到context容器中,与annotation-driven相关的是 AnnotationDrivenBeanDefinitionParser,先把嵌套组件封装成 BeanComponentDefinition 注册到parsercontext中,然后在注册到beanfactory中
5.beanpostprocessor什么时候注册到容器中的?
答:在容器refresh的第二个步骤 obtainFreshBeanFactory中,loadbeandefiniton解析xml文件中的mvn:componentscan标签是加入的。实际完成这个动作的是 ComponentScanBeanDefinitionParser,扫描到的类会封装成SimpleAnnotationMetadataReadingVisitor,除了会注册扫描到的带有@Component的注解还会额外注册内置的postprocessor。
6.后置处理器的功能是如何作用到Bean上面的?
答:Bean在完成实例化后,所有的后置处理器都会挨个对Bean进行后置处理。例如 AutowiredAnnotationBeanPostProcessor
的 postProcessMergedBeanDefinition 方法通过遍历所有的Bean可以找到字段或者方法或者构造器上面有@Autowired和@Value的类,用于后面 postProcessProperties方法
的依赖注入
7.依赖注入的原理?
答:负责Autowired依赖注入的是AutowiredAnnotationBeanPostProcessor ,在populatebean方法中生效
具体做依赖注入的是postprocessProperties方法,调用 inject 方法 通过反射给需要注入的字段赋值。值得注意的是要被注入的对象还没有在容器中没有实例化初始化,会先出发被依赖对象的实例化初始化,然后再设置到目标中 beanFactory.resolveDependency