先搭一个框架,简单介绍,以后再补充。
准备spring环境:
1 @org.junit.Test 2 public void test01(){ 3 //把spring所有环境准备好 4 // 1.准备好DefaultListableBeanFactory 5 // 实例化一个bdReader和一个Scanner 6 AnnotationConfigApplicationContext applicationContext = 7 new AnnotationConfigApplicationContext(); 8 9 //把一个class转成bd,最后put到map 10 applicationContext.register(AppConfig.class); 15 16 //初始化spring的环境 17 applicationContext.refresh(); 18 19 20 }
构造方法
进入AnnotationConfigApplicationContext类:
1.调用AnnotationConfigApplicationContext()构造方法的时候,会先调用父类构造器new出一个工厂DefaultListableBeanFactory。
1 //new一个工厂DefaultListableBeanFactory 2 public GenericApplicationContext() { 3 this.beanFactory = new DefaultListableBeanFactory(); 4 }
2.初始化一个bean的读取器AnnotatedBeanDefinitionReader和一个扫描器ClassPathBeanDefinitionScanner。
reader可以读取被加了注解的类,scanner可以扫描所有加了注解的bean。
1 public AnnotationConfigApplicationContext() { 2 /** 3 * 父类的构造方法 4 * 创建一个读取注解的BeanDefinition读取器 5 * 什么是bean定义?BeanDefinition 6 */ 7 //reader能够读取被加了注解的类 this是一个注册器,用来将BeanDefinition转为工厂中的map 8 this.reader = new AnnotatedBeanDefinitionReader(this); 9 //可以用来扫描包或者类,继而转换成bd 10 //但是实际上我们扫描包工作不是scanner这个对象来完成的 11 //是spring自己new的一个ClassPathBeanDefinitionScanner 12 //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法 13 this.scanner = new ClassPathBeanDefinitionScanner(this); 14 }
3.进入this.reader = new AnnotatedBeanDefinitionReader(this)方法,一直到:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source)
3.1 该方法中首先调用了unwrapDefaultListableBeanFactory()方法,这样获取到工厂。当前的工厂是一个空的工厂,给工厂设置依赖比较器(应该是这样翻译的吧),设置处理延迟加载的功能。
3.2 设置BeanDefinitionHolder(装的是beanName+BeanDefinition,基本没啥作用,只是为了传参方便,本来传beanName和BeanDefinition,现在传BeanDefinitionHolder就可以)。org.springframework.context.annotation.internalConfigurationAnnotationProcessor
3.3 将ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,EventListenerMethodProcessor ,DefaultEventListenerFactory 6个
spring的内置的类转为6个RootBeanDefinition,然后注册器BeanDefinitionRegistry将这些个类注册进工厂,最后这个RootBeanDefinition转换成beanName+BeanDefinition的方式放入BeanDefinitionHolder。
该registerAnnotationConfigProcessors方法的目的就是将ConfigurationClassPostProcessor类以及其他内置类装入BeanDefinitionHolder,然后返回BeanDefinitionHolder。
接下来回到2。然后是研究this.scanner = new ClassPathBeanDefinitionScanner(this)。这个scanner的作用基本很小,如果在外部比如调用applicationContext.scan("")方法才会利用到。否则一切的扫描注册和它没有啥关系。
这样,AnnotationConfigApplicationContext()构造完成。
注册
接下来就是注册。进入applicationContext.register(AppConfig.class)方法。
4.进入doRegisterBean()方法:
(1)先把要注册的bean转为AnnotatedGenericBeanDefinition(AGBD),AnnotatedGenericBeanDefinition包括了bean的其他信息,比如一些元信息,scope,lazy等。
(2)把类的作用域的名字添加到AGBD中,并且得到注册bean的名字。processCommonDefinitionAnnotations()方法将AGBD中的信息拿出来进行处理,主要处理一些常用的注解,处理完成放回AGBD。
(3)把AnnotatedGenericBeanDefinition装入BeanDefinitionHolder,然后BeanDefinitionRegistry把BeanDefinitionHolder中的信息(bean)注册进入工厂。
初始化Spring环境
5.进入refresh()方法。
(1)调用prepareRefresh()方法,这是刷新前的准备工作。获取容器的当时时间,同时给容器设置同步标识。
(2)refresh()-->obtainFreshBeanFactory()-->refreshBeanFactory()获取工厂
(3)调用prepareBeanFactory(beanFactory):给工厂设置ClassLoader,bean表达式解释器,添加后置处理器beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))到工厂中的一个list中,在bean实例化的时候在拿出来插手。
(4)postProcessBeanFactory(beanFactory)
(5)invokeBeanFactoryPostProcessors(beanFactory),实例化并调用所有已注册BeanFactoryPostProcessor的bean,
必须在单例bean实例化之前调用。
----->invokeBeanFactoryPostProcessors(beanFactory)
------->invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors()):getBeanFactoryPostProcessors()方法获取自己定义的,没有@Component的后置处理器。继续进入invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors())方法:
a.判断beanFactory的类型是不是和注册器BeanDefinitionRegistry一个类型。如果是的话,创建两个list,一个是BeanFactoryPostProcessor类型,一个是BeanDefinitionRegistryPostProcessor类型。BeanDefinitionRegistryPostProcessor其实也是继承自BeanFactoryPostProcessor,就是多扩展了一个方法。这两个list都是处理我们自己定义的后置处理器。
b.建立一个BeanDefinitionRegistryPostProcessor类型的list叫做currentRegistryProcessors,这个list是处理Spring自带的后置处理器,并不是我们定义的,和a中的要有所区分。在3.3中spring已经把自己内部的6个后置处理器放入beanFcatory中了。现在根据BeanDefinitionRegistryPostProcessor取出子类放入currentRegistryProcessors。这样的话,就可以让子类去完成一些事,避免了高度耦合。
c.把a和b中类型为BeanDefinitionRegistryPostProcessor的list合并,也就是把我们定义的和spring内置的后置处理器放在一块。然后调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法,进入方法调用扩展方法postProcessBeanDefinitionRegistry(registry)方法,也就是子类要实现该方法。这也是一个扩展点。目前学到的有三个扩展点:BeanPostProcessor,BeanPostFactoryProcessor,BeanDefinitionRegistryPostProcessor。BeanDefinitionRegistryPostProcessor继承自BeanPostFactoryProcessor,但是又在BeanPostFactoryProcessor的基础上进行了扩展。
d.接着c讲,BeanDefinitionRegistryPostProcessor的子类ConfigurationClassPostProcessor实现了postProcessBeanDefinitionRegistry(registry)方法,进入方法,调用了processConfigBeanDefinitions(registry)方法。在这个方法中,取出工厂中所有的BeanDefinition,包括自定义的以及spring内置的。从每一个BeanDefinition获取到原始bean的元信息,判断bean是不是加了@Configuration注解。如果是,加入到BeanDefinitionHolder的list中,如果不是,再继续判断是否加了@Component,@ComponentScan,@Import,@ImportResource这些注解,如果是,同样加入到BeanDefinitionHolder的list中。接下来就是解析这些加了注解的类。调用parser.parse(candidates)方法进行解析。parse方法中调用了另外的parse(AnnotationMetadata,beanName)方法来进行解析。继续调用processConfigurationClass()方法,继续调用doProcessConfigurationClass()方法,在该方法中,处理@ComponentScan的信息。调用this.componentScanParser.parse()方法,该方法中定义了一个ClassPathBeanDefinitionScanner作为扫描器,继续调用scanner.doScan()方法,这个方法是很重要的方法,用来扫描包。首先定义一个BeanDefinitionHolder,负责装扫描出来的BeanDefinition。调用findCandidateComponents(basePackages)方法,扫描basePackage路径下的java文件,符合条件的并把它转成BeanDefinition类型。调用scanCandidateComponents(String basePackage)方法,把.class文件扫描出来。