ConfigurationClassPostProcessor
在AnnotationConfigEmbeddedWebApplicationContext构造方法中创建
在invokeBeanFactoryPostProcessors()步骤中执行
接口主要实现了BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor 接口
在启动的时候会先执行BeanDefinitionRegistryPostProcessor接口的方法postProcessBeanDefinitionRegistry
再执行BeanFactoryPostProcessor接口的方法postProcessBeanFactory
只记录重点参数
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
--> processConfigBeanDefinitions(BeanDefinitionRegistry)
从BeanDefinitionRegistry中得到所有注册的beanDefinition
这里就会得到步骤prepareContext()将new SpringApplication(AppBarrageRobotApplication.class)的AppBarrageRobotApplication加入到beanFactory中的AppBarrageRobotApplication
进而可以扫描到启动类AppBarrageRobotApplication上面的注解
--> checkConfigurationClassCandidate(BeanDefinition)
找到所有包含Configuration Component ComponentScan Import ImportResource的BeanDefinition 或者有Bean注解的方法
Configuration的bean会加上full标志
其余的会标志lite标志
加入configCandidates list集合
--> 创建ConfigurationClassParser对象parser,用来解析上面的那些BeanDefinition集合configCandidates,这里将list转成了LinkedHashSet candidates
--> parser.parse(candidates) while do 循环解析刚刚得到的BeanDefinition集合candidates,循环的原因是因为解析的过程中可能会有新的BeanDefinition包含那些注解 注意这里传进去的是整个集合
遍历刚刚传进来集合的元素
-->1 processConfigurationClass(ConfigurationClass configClass) ConfigurationClass是将注解信息与beanName封装在一起的对象
--> 根据configClass创建SourceClass
--> doProcessConfigurationClass(configClass,sourceClass)
--> processMemberClasses(configClass, sourceClass) 处理内部类 调用processConfigurationClass()方法继续解析被发现的配置类
--> ComponentScanAnnotationParser对象处理ComponentScans ComponentScan注解
得到要扫描的包下面的类resource,过滤找到Component注解的类封装成ScannedGenericBeanDefinition集合
针对上一步得到的集合,遍历调用processConfigurationClass(ConfigurationClass)(上面第一步)
--> processImports(...)处理Import注解
实现了ImportSelector接口的话,如果还实现了DeferredImportSelector接口,就加入deferredImportSelectors集合,后面再执行;否则就执行selectImports方法
得到被引入的类的集合,将集合重新执行processImports(...)处理Import注解
如果实现了ImportBeanDefinitionRegistrar接口,那么就放入configClass的importBeanDefinitionRegistrars中,等待后续处理
以上都不是的话说明引入的是普通bean,调用第一步的processConfigurationClass递归执行
--> 处理ImportResource注解,将解析出啦的资源放入configClass的importedResources中,等待后续处理
--> 处理带有Bean注解的方法,封装成MethodMetadata放入configClass的beanMethods中,等待后续处理
--> 将刚刚处理过的ConfigurationClass放入ConfigurationClassParser对象parser的configurationClasses中
--> processDeferredImportSelectors() 处理刚刚加入deferredImportSelectors集合的DeferredImportSelector实现类
遍历执行selectImports方法,得到被引入的类的集合,将集合重新执行processImports(...)处理Import注解
--> parser.validate() 校验刚刚configurationClasses集合中的对象 如果有Configuration注解,那么就要能被继承和被重写(不能是final类型的类)
--> 通过ConfigurationClassBeanDefinitionReader对象的loadBeanDefinitions(configurationClasses)方法将刚刚parser的configurationClasses集合全部注册到beanFactory中beanDefinitionMap
postProcessBeanFactory(beanFactory)
--> enhanceConfigurationClasses(beanFactory) 采用cglib给注解了Configuration的做代理(主要原因 对调用有Bean注解的方法进行代理,让其多次调用只生成一次对象,返回一个单例对象 以及处理 factoryBean相关东西)
方法拦截类有BeanMethodInterceptor BeanFactoryAwareMethodInterceptor 两个
BeanMethodInterceptor
第一个条件,不能是Object,这个必定是满足的
第二个条件,不能是setBeanFactory方法,显而易见的嘛,我们要拦截的方法实际只应该是添加了Bean注解的方法
第三个条件,添加了Bean注解
对调用有Bean注解的方法进行代理,让其多次调用只生成一次对象,返回一个单例对象 以及处理 factoryBean相关东西
BeanFactoryAwareMethodInterceptor
在调用setBeanFactory方法时才会拦截
代理类中添加一个字段,BEAN_FACTORY_FIELD = "$$beanFactory" 并设置beanFactory
--> 向beanFactory中添加ImportAwareBeanPostProcessor