Spring相关的核心概念总览(粗略)

117 阅读4分钟

笔记大纲

  • 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( )。