Spring源码解析笔记(一)
本文由colodoo(纸伞)整理
QQ 425343603
Java学习交流群(717726984)
参考 https://www.bilibili.com/vide... 1-10章节
BeanDefinition
BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念。
@Component、@Bean、
配置属性包含
- beanClass
- scope
- isLazy
- dependsOn
- primary
- initMethodName
beanClass
表示一个bean的类型,比如UserService.class、OrderService.class,Spring在创建Bean 的过程中会根据此属性来实例化得到对象。
scope
表示一个bean的作用域,比如:
scope等于singleton,该bean就是一个单例Bean;
scope等于prototype,该bean就是一个原型bean。
isLazy
表示一个bena是不是需要懒加载,原型bean的isLazy属性不起作用,懒加载的单例bean,会在第一次getBean的时候生成该bean,非懒加载的单例bean,则会在Spring启动过程中直接生成好。
dependsOn
表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它错依赖的这些bean得先全部创建好。
primary
表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性。
initMethodName
表示一个bean得初始化方法,一个bean的生命周去过程中有一个步骤叫初始化,Spring会在这个步骤中取调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工。
BeanFactory
BeanFactory是一种“Spring容器”,BeanFactory翻译过来就是Bean工厂;它可以用来创建Bean、获取Bean,BeanFactory是Spring中非常核心的组件。
BeanDefintion、BeanFactory、Bean 关系
BeanFactory将利用BeanDefinition来生成Bean对象,BeanDefinition相当于BeanFactory的原材料,Bean对象就相当于BeanFactory所生产出来的产品。
BeanFactory利用BeanDefinition产出Bean对象。
核心子接口和实现类
- ListableBeanFactory
- ConfigurableBeanFactory
- AuwowireCapableBeanFactory
- AbstractBeanFactory
- DefaultListableBeanFactory
DefaultListableBeanFactory
支持单例Bean、支持Bean别名、支持父子BeanFactory、支持Bean类型转化、支持Bean后置处理、支持FactoryBean、支持自动装配,等等。
Bean生命周期
生命周期的几个阶段:
- BeanDefinition -> Bean定义
- 构造方法推断 -> 选出构造方法
- 实例化 -> 构造方法反射实例化对象
- 属性填充 -> 自动填充属性
- 初始化 -> 对其他属性赋值、校验
- 初始化后 -> AOP、生成代理对象
BeanDefinition
BeanDefinition表示Bean定义,它定义了某个Bean的类型,Spring就是利用BeanDefinition来创建Bean的,比如需要利用BeanDefinition中beanClass属性确定Bean的类型,从而实例化出来对象。
构造方法推断
一个Bean中可以有多个构造方法,此时就需要Spring来判断到底使用哪个构造方法,这个过程是比较复杂的,篇幅有限,不展开介绍。通过构造方法推断之后确定一个构造方法后,就可以利用构造方法实例化得到一个对象了。
实例化
通过构造方法反射得到一个实例化对象,在Spring中,可以通过BeanPostProcessor机制对实例化进行干预。
属性填充
实例化所得到的对象,是“不完整”的对象,“不完整”的意思是该对象中的某些属性还没有进行属性填充,也就是Spring还没有自动给某些属性赋值,属性填充就是我们通常说的自动注入、依赖注入。
初始化
在一个对象的属性填充之后,Spring提供了初始化机制,程序员可以利用初始化机制对Bean进行自定义加工,比如可以利用InitializingBean接口来对Bean中的其他属性进行赋值,或对Bean中的某些属性进行校验。
@Autowired
@Autowired表示某个属性是否需要进行依赖注入,可以写在属性和方法上。注解中的required属性默认为true,表示如果没有对象可以注入给属性则抛异常。
@Service
public class OrderService {
@Autowired
private UserService userService;
}
@Autowired加在某个属性上,Spring在进行Bean的生命周期过程中,在属性填充这一步,会基于实例化出来的对象,对该对象中加了@Autowired的属性自动给属性赋值。
Tip:操作步骤是在属性填充这一步。
构造方法
@Autowired加在构造方法上时,Spring会在推断构造方法阶段,选择该构造方法来进行实例化,在反射调用构造方法之前,会先根据构造方法参数类型、参数名从Spring容器中找到Bean对象,当作构造方法入参。
@Resource
@resource如果name属性有值,那么Spring会直接根据所指定的name值取Spring容器找Bean对象,如果找到了则成功,没有找到则报错。
@Value
@Value注解和@Resource、@Autowired类似,也是用来对属性进行依赖注入的,只不过@Value是用来从Properties文件中获取值的,并且@Value可以解析SpEL(Spring表达式)。
FactoryBean
FactoryBean是Spring所提供的一种较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象。
接口方法:
- Object getObject():返回的是Bean对象
- boolean isSingleton():返回的是否是单例Bean对象
- Class getObjectType():返回的是Bean对象的类型
代码:
@Component( "demo")
public class DemoFactoryBean implements FactoryBean {
@Override
public 0bject get0bject() throws Exception {
return new Demo();
}
@Override
public class get0bjectType() {
return Demo.class;
}
@Override
//所定义的Bean是单例还是原型
public boolean issingleton() {
return true;
}
}
FactoryBean机制被广泛的应用在Spring内部和Spring与第三方框架或组件的整合过程中。
FactoryBean和BeanFactory
FactoryBean
FactoryBean对象本身也是一个Bean,同事它相当于一个小型工厂,可以生产出另外的Bean。
BeanFactory
BeanFactory是一个Spring容器,是一个大型工厂,它可以生产出各种各样的Bean。
ApplicationContext
ApplicationContext是比BeanFactory更加强大的Spring容器,它既可以创建bean、获取bean,还支持国际化、事件广播、获取资源等BeanFactory不具备的功能。
继承接口
- EnvironmentCapable
- ListableBeanFactory
- HierarchicalBeanFactory
- MessageSource
- ApplicationEventPublisher
BeanPostProcessor
BeanPostProcessor在Spring中是一个接口,我们定义一个后置执行器,就是提供一个类实现该接口,在Spring中还存在一些接口继承了BeanPostProcessor,这些接子接口是在BeanPostProcessor的基础上增加了一些其他的功能。
BeanPostProcessor中的方法
postProcessBeforelnitialization():初始化前方法,表示可以利用这个方法来对Bean在初始化前进行自定义加工。
postProcessAfterlnitialization):初始化后方法,表示可以利用这个方法来对Bean在初始化后进行自定义加工。
InstantiationAwareBeanPostProcessor
BeanPostProcessor的一个子接口,
postProcessBeforelnstantiation():实例化前
postProcessAfterlnstantiation():实例化后postProcessProperties():属性注入后
AOP
Aop就是面向切面编程,是一种非常适合在无需修改业务代码的前提下,对某个或某些业务增加统一的功能,比如日志记录、权限重置、事务管理等,能很好的使得代码解耦,提高开发效率。
- Advice
- Pointcut
- Advisor
- Weaving
- Target
- Join Point
Advice
Advice可以理解为通知、建议,在Spring中通过定义Advice来定义代理逻辑。
Pointcut
Pointcut是切点,表示Advice对应的代理逻辑应用在哪个类、哪个方法上。
Advisor
Advisr等于Advice+Pointcut,表示代理逻辑和切点的一个整体,程序员可以通过定义或封装一个Advisor,来定义切点和代理逻辑。
Weaving
Weaving表示织入,将Advicedialing逻辑在源代码级别嵌入到切面得过程,就叫做织入。
Target
Target表示目标对象,也就是被代理对象,在AOP生成的代理对象中对持有目标对象。
Join Point
Join Point表示连接点,在Spring AOP中,就是方法的执行点。
AOP工作原理
AOP是发生在Bean的生命周期过程中的;
- Spring生成bean对象时,先实例化出来一个对象,也就是target对象。
- 再对target对象进行属性填充。
- 在初始化步骤中,会判断target对象有没有对应的切面。
- 如果有切面,就表示当前target对象需要进行AOP。
- 通过Cglib或JDK动态代理机制生成一个代理对象,作为最终的bean对象。
- 代理对象中有一个target属性只想了target对象。