Spring 部分概念简述

1. BeanDefinition

1. wiki

表说 Bean 的定义,Spring 根据它来创建 Bean 对象。常用的 @Component@Bean@<bean/> 都会解析为 BeanDifinition

2. 组成

  • beanCalss:表示一个 bean 的类型。比如:UserService.class,Spring 在创建 Bean 的过程中会根据此属性来实例化得到对象。
  • scope:表示一个 bean 的作用域。singletion 表示 该 bean 就是一个单例,prototype,该 bean 就是一个原型。
  • isLazy:表示一个 bean 是不是需要懒加载。原型 bean 的 isLazy 属性不起作用;懒加载的单例 bean 会在第一次 getBean 的时候生成该 bean ,非懒加载的单例 bean 则会在 Spring 启动过程中直接生成好。
  • dependsOn:表示一个 bean 在创建之前所依赖的其它 bean,在创建之前,他所依赖的这些 bean 得先全部创建好。
  • primary:表示一个 bean 是主 bean。在 Spring 中一个类型可以有多个 bean 对象,在进行依赖注入时,如果根据类型找到多个 bean,此时会判断这些 bean 是否有一个主 bean,如果存在,则直接将这个 bean 注入属性。
  • initMethodName:表示一个 bean 的初始化方法。在 Spring 生命周中可以自定义初始化逻辑。

2. BeanFactory

1. wiki

是一种 Spring 容器,可以用来创建、获取 Bean。利用 BeanDifinition 生成 bean 对象

2. 核心子接口和实现类

  • ListableBeanFactory
  • ConfigurableBeanFactory
  • AutowireCapableBeanFactory
  • AbstractBeanFactory
  • DefaultListableBeanFactory:支持单例bean、bean别名、父子BeanFactory、bean类型转化、bean后置处理、FactoryBean、自动装配等

3. Bean 生命周期

  • BeanDefinition:bean 定义
  • 构造方法推断:选择一个构造方法
  • 实例化:构造方法反射得到对象,可以通过 BeanPostProcessor 进项干预
  • 属性填充:给部分属性进行自动填充,即依赖注入
  • 初始化:对其它属性赋值、校验,可以利用 InitializingBean 接口对其他属性进行赋值
  • 初始化后:AOP、生成代理对象

4. @Autowire

1. wiki

表示属性是否需要进项依赖注入,可以在属性和方法上。

  • 写在属性上时:Spring 在容器中找 bean 类型,先根据属性类型查找,如果找到多个时,则根据属性名挑选一个。注解中的 required 属性默认为 true ,表示如果没有对象可以注入给属性则抛出异常。
  • 写在方法上时:Spring 会在bean属性填充阶段,根据方法参数类型、参数名字从容器中找到并作为入参,自动反射调用该方法。
  • 写在构造方法上时:Spring 会在推断构造方法阶段,根据方法参数类型、参数名字从容器中找到并作为入参,自动反射调用该方法。

5. @Resource

1. wiki

@Autowire 一样是提供依赖注入的,但是 @Resource是 java 层面提供的,@Autowire 是 Spring 提供的。
@Resource有个 name 属性,根据 name 属性是否有值,依赖注入的底层流程不一样的:

  • 有值,则直接根据指定 name 值去容器中找,没找到则报错
  • 无值,则先判断属性名字是否在容器中存在,没找到则根据属性类型去找,否则报错

6. @Value

@Autowire@Resource 类似,也是对属性进行依赖注入,只不过 @Value 是从 properties 文件中获取值,并且其可以解析 SpEL 表达式。

  • @Value("hello"):直接赋值给属性,如果属性类型不是String或无法记性类型转化,则报错。
  • @Value("${hello}"):会把 ${} 中字符串当做 key 从 properties 文件查找对应 value 赋值给属性,没找到则把 ${hello} 赋值给属性。
  • @Value("#{hello}"):会把 #{} 中字符串当做 beanName ,并从容器中找对应 bean,没找到则报错。

7. FactoryBean

1. wiki

Spring 提供的一种灵活创建 bean 的方式,可以通过 FactoryBean 接口中的 getObject() 方法返回一个对象,其为最终对象。

2. 接口中方法

  • Object getObject():返回的是 bean 对象
  • boolean isSingleton():返回的是否是单例 bean 对象
  • Class getObjectType():返回的是 bean 对象类型

8. ApplicationContext

1. wiki

是比 BeanFactory 更加强大的 Spring 容器,其既可以创建、获取 bean,还可以支持国际化、事件广播、获取资源等。

2. 继承的接口

  • EnvironmentCapable:通过它获取操作系统和JVM环境变量
  • ListableBeanFactory:通过它获取所有beanNames、判断某个bean是否存在beanDefinition对象、统计beanDefinition个数、获取某个类型对应的所有beanNames等功能
  • HierarchivalBeanFactory:可以通过它获取父BeanFactory、判断某个name是否存在bean对象的功能
  • MessageSource:通过它获得国际化功能,可以直接利用 MessageSource 对象获取某个国际化资源
  • ApplicationEventPublisher:通过它获得事件发布功能
  • ResourcePatternResolver:通过它获得加载和获取资源功能,资源可以是文件或者图片、url资源等

9. BeanPostProcessor

1. wiki

bean后置处理器,可以定制化 bean。其是一个接口,可以实现该接口来增加一些功能。

2. 接口中方法

  • postProcessBeforeInitialization():初始化前方法,可在初始化前进行自定义
  • postProcessAfterInitialization():初始化后方法

10. AOP

1. wiki

面向切面编程,无需修改业务代码前提下,对某个或某些业务增加统一的功能,比如日志记录、权限控制、事务管理等

2. 核心概念

  • Advice:用来定义代理逻辑
  • Pointcut:切点,表示 Advice 对应的代理逻辑应用在哪个类、方法上
  • Advisor:等于 Advice+Pointcut
  • Weaving:织入,将 Advice 代理逻辑在源代码级别嵌入到切点的过程
  • Target:代理对象,在 AOP 生成代理对象中会持有对象
  • Join Point:连接点,值方法的执行点

3. 工作原理

  1. Spring 生成 bean 对象时,先实例化一个对象,即 Target
  2. 对 Target 对象进行属性填充
  3. 在初始化后步骤中,会判断 Target 对象有没有对应切面
  4. 如果有切面,就表示当前 Target 对象需要进行 AOP
  5. 通过 Cglib 或者 JDK 动态代理机制生成一个代理对象,作为最终 bean 对象
  6. 代理对象中有一个 Target 属性指向了 Target 对象