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+PointcutWeaving
:织入,将 Advice 代理逻辑在源代码级别嵌入到切点的过程Target
:代理对象,在 AOP 生成代理对象中会持有对象Join Point
:连接点,值方法的执行点
3. 工作原理
- Spring 生成 bean 对象时,先实例化一个对象,即 Target
- 对 Target 对象进行属性填充
- 在初始化后步骤中,会判断 Target 对象有没有对应切面
- 如果有切面,就表示当前 Target 对象需要进行 AOP
- 通过 Cglib 或者 JDK 动态代理机制生成一个代理对象,作为最终 bean 对象
- 代理对象中有一个 Target 属性指向了 Target 对象