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. 核心子接口和实现类
ListableBeanFactoryConfigurableBeanFactoryAutowireCapableBeanFactoryAbstractBeanFactoryDefaultListableBeanFactory:支持单例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 对象
