getBean() 方法中调用了 doGetBean() 方法,doGetBean() 方法中调用了 createBean() 方法,createBean() 方法中调用了 doCreateBean() 方法。根据这个四个方法的名称我们可以通过见其名知其意的定义原则,我们可以猜想 getBean() 方法和 doGetBean() 方法是尝试获取现有的Bean;createBean() 方法和 doCreateBean() 方法是新创建一个Bean。
我们要带着问题去学习,学习后要进行总结,接下来我们依次来贴上每个方法的原代码进行关键代码解读(一些辅助性的代码不做解读)。声明:我们解读的BeanFactory实现类是 DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory extends AbstractBeanFactory extends FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry extends SimpleAliasRegistry
目录
一、学习前的疑问?
1.1 bean的实例化在哪个时间点进行的?有哪些方式可以实例化?有没有扩展点?
1.2 bean的属性赋值在哪个时间点进行的?有哪些方式可以给bean的属性赋值?有没有扩展点?
1.3 bean的初始化方法调用在哪个时间点进行的?有哪些方式可以给bean进行初始化,有没有扩展点?
1.4 实例化、属性赋值、初始化、这三个阶段的执行顺序谁先谁后?
1.5 我们所谓的依赖注入是怎么实现的?
1.6 我们所谓的创建代理对象是怎么实现的?
二、学习源代码
2.1 getBean() 方法
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
String beanName = transformedBeanName(name); // 从一级缓存获取,要是没有获取到再从二级缓存中获取。如果获取到了则说明这个Bean已经被创建过了 // 从缓存中没有找到,走创建流程 else { // Check if bean definition exists in this factory. if (!typeCheckOnly) { StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") // 以下这段代码是在创建当前Bean之前先创建当前Bean的依赖Bean // Guarantee initialization of beans that the current bean depends on. // 如果创建的是一个单例Bean // 以下代码执行的逻辑是: 1 先从一级缓存中获取,获取到了直接返回结果 2 如果一级缓存中没有获取到,就调用 createBean() 方法,声明:createBean()方法有前置钩子方法和后置钩子方法 // 如果创建的是一个多例Bean else if (mbd.isPrototype()) { else { return adaptBeanInstance(name, beanInstance, requiredType); |
2.2 createBean() 方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
if (logger.isTraceEnabled()) { // Make sure bean class is actually resolved at this point, and // Prepare method overrides. try { // 这是一个扩展的地方,扩展接口 InstantiationAwareBeanPostProcessor 这样的Bean的 postProcessBeforeInstantiation() 方法返回了一个非Null对象,就直接返回这个Bean了,不再走doCreateBean()流程了。 try { protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) // Instantiate the bean. // 创建Bean的实例(说白了就是反射调用构造器方法) // Allow post-processors to modify the merged bean definition. // 这是一个扩展的地方,扩展接口 MergedBeanDefinitionPostProcessor // 这个方法会调用所有Bean中实现了 MergedBeanDefinitionPostProcessor 接口的postProcessMergedBeanDefinition()方法 // Eagerly cache singletons to be able to resolve circular references // 三级缓存解决的问题是有代理对象间的循环依赖 // 这个方法的作用是如果一级缓存中不存在这个Bean,就把Bean中从二级缓存中移除,把 getEarlyBeanReference()方法的实现装进第三级缓存中,如果从第三级缓存中获取对象的时候就会调用这个getEarlyBeanReference()方法 // Initialize the bean instance. // 这个方法实现Bean的依赖注入 // 这个方法是实现Bean的初始化(说白了就是调用相关初始化方法) ...省略代码 return exposedObject; protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 这段代码的意思是:所有Bean中实现了 InstantiationAwareBeanPostProcessor接口的 postProcessAfterInstantiation()方法返回false则不再走依赖注入流程了 // 以下代码是收集依赖注入信息,比如属性是通过名字注入还是通过类型注入 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 这里是一个扩展点 扩展接口 InstantiationAwareBeanPostProcessor // 以下代码是收集依赖Bean的实例,然后进行依赖注入 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); PropertyDescriptor[] filteredPds = null; PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (pvs != null) { // 实现依赖注入 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { // 1 先调用一些容器内置接口,如果bean实现了 BeanNameAware BeanClassLoaderAware BeanFactoryAware 则调用对应的方法 Object wrappedBean = bean; // 这里是一个扩展点,扩展接口 BeanPostProcessor // 在bean初始化前进行一些处理,比如自定义注解的依赖注入 try { // 调用bean的初始化方法,比如:如果bean实现InitializingBean接口则调用 afterPropertiesSet()方法,如果有定义自定义初始化方法,则也进行调用 // 在bean初始后进行一些处理,比如:代理对象的创建就是在这一步切入的 return wrappedBean;
} |
三、学习后的总结
3.1 bean的实例化在哪个时间点进行的?有哪些方式可以实例化?有没有扩展点?
答:
时间点:一开始的时候
实例化方式:
1 如果 bean的定义中指定了 Supplier的实现类,就由这个指定的实现类负责实例化bean
2 如果bean的定义中指定工厂方法(factoryMethod),就由这个指定的工厂方法负责实例化bean
3 如果设置了 SmartInstantiationAwareBeanPostProcessor的实现类,就由这些实现类提供bean的构造器,然后通过这些构造器进行实例化
4 如果bean的定义中指定了构造器,则由这个指定的构造器进行实例化
5 以上都没有满足,由默认使用无参构造器进行实例化
扩展接口:
SmartInstantiationAwareBeanPostProcessor 接口是一个扩展接口,可以通过这个扩展接口提供指定的构造器进行实例化
3.2 bean的属性赋值在哪个时间点进行的?有哪些方式可以给bean的属性赋值?有没有扩展点?
答:
时间点:bean实例化后-再 MergedBeanDefinitionPostProcessor 扩展接口 的所有实现类的 postProcessMergedBeanDefinition() 方法调用完后
属性赋值的方式:
1 扩展接口 InstantiationAwareBeanPostProcessor 的所有实现类的postProcessAfterInstantiation()方法可以给bean实例进行属性赋值
2 扩展接口 InstantiationAwareBeanPostProcessor 的所有实现类的postProcessProperties()方法 和 postProcessPropertyValues()方法 先收集bean所依赖的实例对象然后进行属性赋值,比如:CommonAnnotationBeanPostProcessor类的postProcessProperties()方法中的实现就可以给bean中有@Resource注解的属性进行赋值;再比如:AutowiredAnnotationBeanPostProcessor类中的postProcessProperties()方法中的实现就可以给bean中有@Autowird注解的属性进行赋值;
3 然后再调用 BeanWrapper 实例的 setPropertyValues()方法进行属性赋值
扩展接口:
InstantiationAwareBeanPostProcessor 是一个扩展接口通过调用 postProcessAfterInstantiation()方法、postProcessProperties()方法、postProcessPropertyValues()方法都可以给bean实例进行属性赋值
InstantiationAwareBeanPostProcessor extends BeanPostProcessor
3.3 bean的初始化方法调用在哪个时间点进行的?有哪些方式可以给bean进行初始化,有没有扩展点?
答:
时间点:bean的属性赋值后,再进行bean的相关初始化方法调用
初始化方式:
1 如果bean实现了 BeanNameAware 接口,则调用 bean的 setBeanName()方法;如果bean实现了 BeanClassLoaderAware 接口,则调用 bean的 setBeanClassLoader()方法;如果bean实现了 BeanFactoryAware接口,则调用 bean的 setBeanFactory()方法;
2 调用所有实现了BeanPostProcessor接口的实例的postProcessBeforeInitialization()方法进行bean初始化前置处理操作。比如 CommonAnnotationBeanPostProcessor的postProcessBeforeInitialization()方法就可以调用有@PostConstruct注解的方法
3 如果bean实现了 InitializingBean 接口,则调用 bean 的 afterPropertiesSet()方法
4 如果 bean的定义中有指定 initMethodName,则调用initMethodName属性指定的自定义方法
5 调用所有实现了BeanPostProcessor接口的实例的postProcessAfterInitialization()方法进行bean初始化后置处理操作。比如:AbstractAutoProxyCreator实例的postProcessAfterInitialization()方法就可以创建一个代理对象
扩展接口:
BeanNameAware 、BeanClassLoaderAware、BeanFactoryAware、是容器内置的扩展接口容器是默认支持的,而 BeanPostProcessor 是容器外置的扩展接口,需要有对应的实现类注册到容器中才能识别和处理指定的注解,比如:给方法上添加@PostConstruct注解、给属性上添加@Resource注解,要是容器中没有注册CommonAnnotationBeanPostProcessor类,则bean的属性赋值阶段@Resource注解的属性就不会进行依赖注入,在bean初始化阶段@PostConstruct注解的方法就不会被调用。
3.4 实例化、属性赋值、初始化、这三个动作间的执行顺序谁先谁后?
答:
先实例化->再属性赋值->后初始化,关于这三个阶段的每一个阶段中内部的先后顺序请参考上面的依次描述。
3.5 我们所谓的依赖注入是怎么实现的?
3.6 我们所谓的创建代理对象是怎么实现的?
请看我的另一篇文章 Spring Aop 源码解读-CSDN博客