启动入口
创建AnnotationConfigApplicationContext
创建AnnotationConfigApplicationContext对象,所有的加载创建操作都在这里进行
//创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(AppClassCofig.class);
//通过AnnotationConfigApplicationContext拿到bean
User user = annotationConfigApplicationContext.getBean("user", User.class);
AnnotationConfigApplicationContext会做什么
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//1、调用父类的构造方法
this();
//2、componentClasses就是我们的配置类,比如被修饰了注解@Configuration的类
register(componentClasses);
//3、刷新,添加扩展器,bean的实例化,等等都在这里处理
refresh();
}
执行父类的构造方法
public AnnotationConfigApplicationContext() {
//创建一个BeanDefinition读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
//创建一个BeanDefinition扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//注册一个读取器,这个读取器很厉害,会创建下面7大后置处理器
this.reader = new AnnotatedBeanDefinitionReader(this);
功能:往BeanDefinitionRegistry注册器里面添加各种“后置处理器”
1、AnnotationAwareOrderComparator(比较器)
2、ContextAnnotationAutowireCandidateResolver(自动装配解析)
3、ConfigurationClassPostProcessor (配置类后置处理器,这个很厉害)
4、AutowiredAnnotationBeanPostProcessor(自动装配后置处理器)
5、CommonAnnotationBeanPostProcessor (普通注解后置处理器)
6、EventListenerMethodProcessor(事件监听器处理器)
7、DefaultEventListenerFactory(事件监听器工厂)
像ConfigurationClassPostProcessor这个后置处理器,会解析带有@Configuration的类
//创建一个扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
参数componentClasses其实就是我们启动的时候穿的参数AppClassCofig.class
向容器里面注册一个类componentClasses,且转成Bean,并把这个bean添加到容器beanDefinitionMap里面去。为什么需要把这个转成Bean,因为后面我们需要通过特殊的类,来解析这个bean,读取这个bean中像@ComponentScan这种注解,来解析需要扫描的路径下的带有@Servcie @Bean…
public void refresh(){
1、prepareBeanFactory(beanFactory);//预准备工作,beanFactory设置添加各种东西
2、invokeBeanFactoryPostProcessors(beanFactory);
3、registerBeanPostProcessors(beanFactory);
4、onRefresh();
5、finishBeanFactoryInitialization(beanFactory);
6、finishRefresh();
}
描述:BeanFactory准备工作。这里面和开始看到那个七个类的作用有很大关系。
总结:
1.设置beanFactory 的类加载器;
2.设置EL表达式解析器(Bean创建完成填充属性时使用)和属性注册解析器
3.利用BeanPostProcessor的特性给各种Aware接口的实现类注入ApplicationContext中对应的属性
4.设置各种Aware接口的实现类为忽略自动装配
5.设置自动装配的类(BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext)
6.如果BeanFactory中存在loadTimeWeaver的bean,那么需要添加动态织入功能
7.注册各种可用组件(environment,systemProperties,systemEnvironment)
细节
1、向BeanFactory中添加BeanPostProcessor:ApplicationContextAwareProcessor
ApplicationContextAwareProcessor的作用请看:跳转
2、向BeanFactory中添加BeanPostProcessor:ApplicationListenerDetector
ApplicationListenerDetector的作用请看:将早期用于检测内部bean的后处理器注册为applicationlistener。兼容以前的后置处理器 跳转
3、向BeanFactory中添加BeanPostProcessor:LoadTimeWeaverAwareProcessor
如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,则把当前BeanFactory交给类加载器BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,从而实现类加载期织入AspectJ的目的。
BeanPostProcessor:LoadTimeWeaverAwareProcessor详细介绍 跳转
4、设置忽略自动装配的接口
设置忽略自动装配的接口,如果注入EnvironmentAware这个bd会注不进来
关注prepareBeanFactory详细介绍可以看:跳转
描述:拿到spring定义和用户定义的BeanFactoryPostProcessors和BeanDefinitionRegistryPostProcessor分别去调用他们的回调方法
1、获取spring自带部分BeanFactoryPostProcessors
这些都是Spring一开启动添加进去的
- ConfigurationWarningsPostProcessor
- CachingMetadataReaderFactoryPostProcessor
- PropertySourceOrderingPostProcessor
2、获取spring自带所有BeanDefinitionRegistryPostProcessor
就包括拿到上面7个后置处理器中的ConfigurationClassPostProcessor,然后执行回调方法,注意ConfigurationClassPostProcessor和internalConfigurationAnnotationProcessor是一个东西
ConfigurationClassPostProcessor会做下面几件事
- 通过getBeanDefinitionNames得到所有beanName
- 找出带有@Configuration的bean,比如SpringBoot项目中加了@SpringBootApplication的类(SpringBootApplication的顶层就包含了@Configuration注解),或者我们平时常用的AppConfigClass这种。
- 创建ConfigurationClassParser对象,并且把配置类作为参数传给ConfigurationClassParser对象,这里会做很多事,解析需要扫描的路径,把这些路劲下的Bean拿到,如果这些Bean又是一个@Config配置类,就递归去扫描解析,像加了@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean都会被处理解析
ConfigurationClassParser和ConfigurationClassPostProcessor是2个东西别搞混了
3、获取所有BeanDefinitionRegistryPostProcessor
上面获取的都是spring自带的BeanDefinitionRegistryPostProcessor,当第二步扫描完全部路径,把需要创建的Bean都是添加进来之后,这些bean里面可能回包含用户自定义的BeanDefinitionRegistryPostProcessor。
4、获取所有BeanFactoryPostProcessor
获取所有BeanFactoryPostProcessor,包含spring定义的和用户定义的,下面5个是spring自带的。
0 = "internalConfigurationAnnotationProcessor"
1 = "servletComponentRegisteringPostProcessor"
2 = "propertySourcesPlaceholderConfigurer"
3 = "ConfigurationPropertiesBindingPostProcessor.store"
4 = "preserveErrorControllerTargetClassPostProcessor"
还会判断这些类型是不是已经执行过了,就是确保只执行了一次,如果没有执行就调用自己实现的回调方法。
拿到所有的BeanPostProcessor,包含spring定义的和用户定义的。把他添加到BeanFactory中里面去,所以也可以说是注册BeanPostProcessor
0 = "internalAutowiredAnnotationProcessor"
1 = "internalRequiredAnnotationProcessor"
2 = "internalCommonAnnotationProcessor"
3 = "internalScheduledAnnotationProcessor"
4 = "ConfigurationPropertiesBindingPostProcessor"
5 = "embeddedServletContainerCustomizerBeanPostProcessor"
6 = "errorPageRegistrarBeanPostProcessor"
7 = "methodValidationPostProcessor"
8 = "dataSourceInitializerPostProcessor"
9 = "persistenceExceptionTranslationPostProcessor"
0= "org.springframework.aop.config.internalAutoProxyCreator"
1、把上面的beanPostProcessor添加到BeanFactory里面去:
beanFactory.addBeanPostProcessor(*)
2、手动添加:BeanPostProcessorChecker,并且把他加入到BeanFactory里面去
3、手动添加: ApplicationListenerDetector
这里会实例化一部分Bean,这些bean是spring的,在额外包括用户自定义的Filter,也就是MVC的相关的bean都会在这里处理
spring自定义的Bean:
1=EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat
2=tomcatEmbeddedServletContainerFactory
3=application
4=WebSocketAutoConfiguration$TomcatWebSocketConfiguration
5=websocketContainerCustomizer
6=HttpEncodingProperties
实例化bean的时候,还会触发BeanPostProcess的回调方法。只要实例化一个bean就会拿到所有的BeanPostProcess然后循环调用,只要有一个bean实例化,循环执行整个BeanPostProcess,所以每个BeanPostProcess可能会执行多次,而BeanFactoryPostProcess是只会执行一次。
实例化剩下没有实例化的Bean,因为onRefresh()方法已经实例化了一部分。
大致看下怎么实例化的:
1、首先拿到所有需要创建Bean的Name
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
2、然后循环遍历里面的name把他转成RootBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
然后通过getBean方法来得到Bean,如果没有实例化,就会同时去创建实例的。
如果是存在循环依赖,就是找出依赖的Bean,然后再去创建这个Bean对象,如果这个Bean又有依赖的Bean,就一层一层递归下去。实例化完了之后就会再去调用BeanPostProcess的回调方法。