笔记大纲
- Spring常用基础组件概念
- Bean的生命周期
- DI的原理
- 构造推断
- AOP
1.BeanDefinition
描述SpringBean的抽象概念,是Java Bean成为Spring Bean的前置条件,是SpringBean的定义。
- class:Bean的类型。
- scope:Bean的作用域。
- initMethodName:Bean的初始化方法。
- lazyinit:Bean是否是懒加载。
- destroyMethodName:Bean的销毁方法。
在程序中可以手动创建BeanDefinition,BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
通过Context的jigisterBeanDefinition方法就可以注册BeanDefinition了。
2.BeanDefinitionReader
- AnnotatedBeanDefinitionReader:可以通过类上的注解将该类转换为对应的BeanDefinition。
- XmlBeanDefinitionReader:通过解析标签来生成BeanDefinition。
3.ClassPathBeanDefinitionScanner
通过扫描指定的包路径,对扫描到的类进行BeanDefinition的解析。 ClassPathBeanDefinitionScanner scanner = **new **ClassPathBeanDefinitionScanner(context); scanner.scan("com.minor");
4.BeanFactory
生产Bean的工厂,定义了生产Bean的抽象方法。其最主要的实现类是DefaultListableBeanFactory
。这个类实现了BeanFatcory接口,还实现了其它很多接口,功能十分的丰富,例如:BeanDefinition的注册、别名功能、获取Bean、获取BeanDefinition相关数据Map等。
5.ApplicationContext
继承自BeanFatory,本质上也是一个Bean工厂,不过增加了其它功能:
- 获取父BeanFactory
- 获取BeanNames的功能
- 国际化支持MessageSource
- 事件广播功能
- 资源加载功能
它有一个重要的实现类:
- AnnotationConfigApplicationContext。
6.Ordered接口、@Order
支持Bean的实例化排序。
7.BeanPostProcessor
Bean的后置处理器,它是一个接口,定义了2个重要的抽象方法:
- postProcessBeforeInitialization
- postProcessAfterInitialization
BeanPostProcessor的功能是在任意Bean的初始化前和后调用相应的方法,也可以在方法里过滤具体的Bean去操作。一般可以通过BeanPostProcessor来拓展SpringBean的实例化流程。
8.BeanFactoryPostProcessor
Bean工厂的后置处理器,和BeanPostProcessor类似,它的目标就是在BeanFactory的实例化过程中对BeanFactory进行操作。只要实现它然后覆盖postProcessBeanFactory方法。
9.FactoryBean
负责生产Bean的Bean,它是一个接口,需要覆盖它的getObject方法,里面可以返回我们具体要返回实例化的Bean。但是getObject实例化出来的Bean不会经过完整的Bean流程,而是只会经过初始化后的流程。
10.MatadataReader、ClassMatadata、AnnotationMetadata
记录class文件的类描述元数据信息,通过ASM字节码技术,快速获取类的元信息,例如类的类型、父类、接口、注解、是否抽象、是否是接口等等数据。以供Spring使用。
11.Bean的生命周期
当容器Context调用getBean( )方法时就会去创建一个对象。在Context初始化的时候通过参数(xml或者类等)解析扫描路径,遍历所有的class文件,找出类上标有@Component等注解的类,封装成对应的BeanDefinition对象放入容器的一个Map中。当容器调用getBean( ),根据入参名字寻找BeanDefinition,然后通过BeanDefinition去创建对象。 1.通过无参构造创建出一个对象,如果有多个构造则进行构造推断操作。 2.判断该类的属性中是否有@Resource、@Autowired等注解,如果有则去容器寻找对应的Bean注 入属性。 3.DI完成以后,Spring检查该类是否实现了一系列的Aware接口,如果实现了就调用实现这些接口 的方法。 4.Spring判断是否有@PostConstruct注解修饰的方法,如果有那么进行调用。 5.Spring判断该类是否实现了InitalizingBean接口,如果实现了,就调用实现了这个接口的方法。 6.Spring通过搜索过滤查看Bean是否需要AOP操作,如果需要就通过动态代理生成代理Bean,然 后放入容器中。 7.当Bean创建完毕以后,如果Bean是单例的,就放入容器的单例池Map中,如果是原型的则不放 入,下次getBean( )的时候重新走流程创建新的Bean。
12.构造推断
如果该类没有写构造方法,那么Spring就是用无参构造。如果这个类有多个构造,并且没有加类似@Autowired的注解来指定用哪个构造,那么Spring会进行构造推断过程: 1.如果类只有1个构造方法,Spirng就调用这个构造。 2.如果类存在多个构造,且未指定,那么Spring判断这几个构造里是否有无参构造,如果有则调用。如果没有,Spring就会抛异常。
13.AOP大概流程
当Bean的初始化完成后,首先Spring会通过如下手段判断Bean是否需要AOP:
1.遍历所有的切面Bean,遍历切面的方法,判断对应的切面是否切到了当前Bean。
2.如果切到了就表示需要AOP进行代理类的生成。
Spring会根据策略选择代理的方式,如果是cglib
方式:
- 创建代理类,代理类继承当前Bean。
- 代理类中重写当前Bean中的方法,target属性就是当前Bean。
- 在重写的方法中,调用具体的切面逻辑,然后调用target的具体方法invoke( )。