Spring IOC 源码解析

Spring IOC 源码解析

此文章部分转载自其余资源,毕竟不能窃读人家的成果,我只是在分享本身所学到的.html

控制反转(IoC)

控制反转(IoC)原理的Spring Framework实现。IoC也称为依赖注入(DI)。这是一个过程,经过这个过程,对象只能经过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖关系(即,它们使用的其余对象)。 。而后容器在建立bean时注入这些依赖项。此过程基本上是bean自己的逆(所以名称,控制反转),经过使用类的直接构造或诸如服务定位器模式的机制来控制其依赖关系的实例化或位置。(官方文档5.x说明)。所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和对象间的关系。java

基于XML的元数据不是惟一容许的配置元数据形式。Spring IoC容器自己彻底与实际编写此配置元数据的格式分离。目前,许多开发人员为其Spring应用程序选择 基于Java的配置面试

有关在Spring容器中使用其余形式的元数据的信息,请参阅:spring

  • 基于注释的配置:Spring 2.5引入了对基于注释的配置元数据的支持。(我这里不解释)
  • 基于Java的配置:从Spring 3.0开始,Spring JavaConfig项目提供的许多功能成为核心Spring Framework的一部分。所以,您可使用Java而不是XML文件在应用程序类外部定义bean。要使用这些新功能,请参阅 @Configuration, @Bean, @Import,和@DependsOn注释。

首先了解什么是spring Bean?spring的bean是具备完整的spring生命周期的对象。数组

那spring生命周期的经历了什么呢?bash

初始化、属性赋值、实例化、销毁。数据结构

spring容器能够称为spring上下文或者spring环境。app

spring容器包含各类组件,如:bean工厂、单例池、读取器、扫描器、处理器、后置处理器等框架

这里将会解释一下:ide

bean的初始化和实例化:

bean的初始化:一个对象被new出来,完成属性方法填充,最后生命周期回调方法执行

bean的实例化:一个类变成bean的过程

Spring的生命周期

Spring的9个后置处理器

流传的大部分博客对spring生命周期的见解

不知道Spring官方对Bean的生命问题是否有明确的定义或者解析,可是Spring In Action以及市面上流传的大部分博客是这样的:

  1. 实例化Bean对象,这个时候Bean的对象是很是低级的,基本不可以被咱们使用,由于连最基本的属性都没有设置,能够理解为连Autowired注解都是没有解析的;
  2. 填充属性,当作完这一步,Bean对象基本是完整的了,能够理解为Autowired注解已经解析完毕,依赖注入完成了;
  3. 若是Bean实现了BeanNameAware接口,则调用setBeanName方法;
  4. 若是Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 若是Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  6. 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  7. 若是Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  8. 若是Bean定义了init-method方法,则调用Bean的init-method方法;
  9. 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
  10. 若是应用的上下文被销毁了,若是Bean实现了DisposableBean接口,则调用destroy方法,若是Bean定义了destory-method声明了销毁方法也会被调用。

基于Java的配置

从这里出发:

AnnotationConfigApplicationContext context=
    new AnnotationConfigApplicationContext(AppConfig.class);
复制代码

AnnotationConfigApplicationContext的结构关系:

建立AnnotationConfigApplicationContext对象

//根据参数类型能够知道,其实能够传入多个annotatedClasses,可是这种状况出现的比较少
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
        //父类的构造函数里面就是初始化DefaultListableBeanFactory,而且赋值给beanFactory
        //本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner
        //scanner的用处不是很大,它仅仅是在咱们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
        this();
        //把传入的类进行注册,这里有两个状况,
        //传入传统的配置类
        //传入bean(虽然通常没有人会这么作
        //看到后面会知道spring把传统的带上@Configuration的配置类称之为FULL配置类,不带@Configuration的称之为Lite配置类
        //可是咱们这里先把带上@Configuration的配置类称之为传统配置类,不带的称之为普通bean
        register(annotatedClasses);
        //刷新
        refresh();
    }
复制代码

咱们先来为构造方法作一个简单的说明:

  1. 这是一个有参的构造方法,能够接收多个配置类,不过通常状况下,只会传入一个配置类。
  2. 这个配置类有两种状况,一种是传统意义上的带上@Configuration注解的配置类,还有一种是没有带上@Configuration,可是带有@Component,@Import,@ImportResouce,@Service,@ComponentScan等注解的配置类,在Spring内部把前者称为Full配置类,把后者称之为Lite配置类。在本源码分析中,有些地方也把Lite配置类称为普通Bean

使用断点调试,经过this()调用此类无参的构造方法,代码到下面:

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    //注解bean定义读取器,主要做用是用来读取被注解的了bean
    private final AnnotatedBeanDefinitionReader reader;

    //扫描器,它仅仅是在咱们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
    private final ClassPathBeanDefinitionScanner scanner;

    /** * Create a new AnnotationConfigApplicationContext that needs to be populated * through {@link #register} calls and then manually {@linkplain #refresh refreshed}. */
    public AnnotationConfigApplicationContext() {
        //会隐式调用父类的构造方法,初始化DefaultListableBeanFactory

        //初始化一个Bean读取器
        this.reader = new AnnotatedBeanDefinitionReader(this);

        //初始化一个扫描器,它仅仅是在咱们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
}
复制代码

首先无参构造方法中就是对读取器reader和扫描器scanner进行了实例化,reader的类型是AnnotatedBeanDefinitionReader,能够看出它是一个 “打了注解的Bean定义读取器”,scanner的类型是ClassPathBeanDefinitionScanner,它仅仅是在外面手动调用.scan方法,或者调用参数为String的构造方法,传入须要扫描的包名才会用到,像这样方式传入的配置类是不会用到这个scanner对象的。

AnnotationConfigApplicationContext类是有继承关系的,会隐式调用父类的构造方法:

下面代码,初始化DefaultListableBeanFactory

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

    private final DefaultListableBeanFactory beanFactory;

    @Nullable
    private ResourceLoader resourceLoader;

    private boolean customClassLoader = false;

    private final AtomicBoolean refreshed = new AtomicBoolean();


    /** * Create a new GenericApplicationContext. * @see #registerBeanDefinition * @see #refresh */
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
}
复制代码

DefaultListableBeanFactory的关系图

DefaultListableBeanFactory是至关重要的,从字面意思就能够看出它是一个Bean的工厂,什么是Bean的工厂?固然就是用来生产和得到Bean的。

让咱们把目光回到AnnotationConfigApplicationContext的无参构造方法,让咱们看看Spring在初始化AnnotatedBeanDefinitionReader的时候作了什么:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }
复制代码

这里的BeanDefinitionRegistry固然就是AnnotationConfigApplicationContext的实例了,这里又直接调用了此类其余的构造方法:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        Assert.notNull(environment, "Environment must not be null");
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
复制代码

让咱们把目光移动到这个方法的最后一行,进入registerAnnotationConfigProcessors方法:

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        registerAnnotationConfigProcessors(registry, null);
    }
复制代码

这又是一个门面方法,再点进去,这个方法的返回值Set,可是上游方法并无去接收这个返回值,因此这个方法的返回值也不是很重要了,固然方法内部给这个返回值赋值也不重要了。因为这个方法内容比较多,这里就把最核心的贴出来,这个方法的核心就是注册Spring内置的多个Bean:

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
复制代码
  1. 判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
  2. 若是不存在(固然这里确定是不存在的),就经过RootBeanDefinition的构造方法得到ConfigurationClassPostProcessorBeanDefinitionRootBeanDefinitionBeanDefinition的子类:
  3. 执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,固然这里注册其余Bean也是同样的流程。

BeanDefinition是什么?

BeanDefinition联系图

它是用来描述Bean的,里面存放着关于Bean的一系列信息,好比Bean的做用域,Bean所对应的Class,是否懒加载,是否Primary等等,这个BeanDefinition也至关重要,咱们之后会经常和它打交道。**

registerPostProcessor方法:

private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

        definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(beanName, definition);
        return new BeanDefinitionHolder(definition, beanName);
    }

复制代码

这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE表明这是spring内部的,并不是用户定义的,而后又调用了registerBeanDefinition方法,再点进去,Oh No,你会发现它是一个接口,没办法直接点进去了,首先要知道registry实现类是什么,那么它的实现是什么呢?答案是DefaultListableBeanFactory:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }

复制代码

这又是一个门面方法,再点进去,核心在于下面两行代码:

//beanDefinitionMap是Map<String, BeanDefinition>,
//这里就是把beanName做为key,ScopedProxyMode做为value,推到map里面
this.beanDefinitionMap.put(beanName, beanDefinition);

//beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去
this.beanDefinitionNames.add(beanName);

复制代码

从这里能够看出DefaultListableBeanFactory就是咱们所说的容器了,里面放着beanDefinitionMap,beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName做为Key,beanDefinition做为Value,beanDefinitionNames是一个集合,里面存放了beanName。打个断点,第一次运行到这里,监视这两个变量:

DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是至关重要的,之后会常常看到它,最好看到它,第一时间就能够反应出它里面放了什么数据

这里仅仅是注册,能够简单的理解为把一些原料放入工厂,工厂尚未真正的去生产。

上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)就是BeanDefinitionRegistryPostProcessor Bean。

ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类,必须紧紧的记住上面所说的这个类和它的继承关系。

除了注册了ConfigurationClassPostProcessor,还注册了其余Bean,其余Bean也都实现了其余接口,好比BeanPostProcessor等。

BeanPostProcessor接口也是Spring的扩展点之一。

至此,实例化AnnotatedBeanDefinitionReader reader分析完毕。

因为常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,因此这里就不看scanner是如何被实例化的了。

把目光回到最开始,再分析第二行代码:

register(annotatedClasses);

复制代码

这里传进去的是一个数组,最终会循环调用以下方法:

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
        //AnnotatedGenericBeanDefinition能够理解为一种数据结构,是用来描述Bean的,这里的做用就是把传入的标记了注解的类
        //转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,能够拿到类上的注解
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

        //判断是否须要跳过注解,spring中有一个@Condition注解,当不知足条件,这个bean就不会被解析
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(instanceSupplier);

        //解析bean的做用域,若是没有设置的话,默认为单例
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());

        //得到beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        //解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

        //限定符处理,不是特指@Qualifier注解,也有多是Primary,或者是Lazy,或者是其余(理论上是任何注解,这里没有判断注解的有效性),若是咱们在外面,以相似这种
        //AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Appconfig.class);常规方式去初始化spring,
        //qualifiers永远都是空的,包括上面的name和instanceSupplier都是一样的道理
        //可是spring提供了其余方式去注册bean,就可能会传入了
        if (qualifiers != null) {
            //能够传入qualifier数组,因此须要循环处理
            for (Class<? extends Annotation> qualifier : qualifiers) {
                //Primary注解优先
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                //Lazy注解
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                //其余,AnnotatedGenericBeanDefinition有个Map<String,AutowireCandidateQualifier>属性,直接push进去
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }

        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
            customizer.customize(abd);
        }

        //这个方法用处不大,就是把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

        //注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
        //DefaultListableBeanFactory维护着一系列信息,好比beanDefinitionNames,beanDefinitionMap
        //beanDefinitionNames是一个List<String>,用来保存beanName
        //beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

复制代码

在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其余参数都是默认值。

  1. 经过AnnotatedGenericBeanDefinition的构造方法,得到配置类的BeanDefinition,这里是否是似曾类似,在注册ConfigurationClassPostProcessor类的时候,也是经过构造方法去得到BeanDefinition的,只不过当时是经过RootBeanDefinition去得到,如今是经过AnnotatedGenericBeanDefinition去得到。

    image.png

  2. 判断需不须要跳过注册,Spring中有一个@Condition注解,若是不知足条件,就会跳过这个类的注册。

  3. 而后是解析做用域,若是没有设置的话,默认为单例。

  4. 得到BeanName。

  5. 解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description。

  6. 限定符处理,不是特指@Qualifier注解,也有多是Primary,或者是Lazy,或者是其余(理论上是任何注解,这里没有判断注解的有效性)。

  7. 把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,能够简单的理解为方便传参)。

  8. 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:

public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {

        //获取beanName
        // Register bean definition under primary name.
        String beanName = definitionHolder.getBeanName();

        //注册bean
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

                //Spring支持别名
        // Register aliases for bean name, if any.
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }

复制代码

这个registerBeanDefinition是否是又有一种似曾类似的感受,没错,在上面注册Spring内置的Bean的时候,已经解析过这个方法了,这里就不重复了,此时,让咱们再观察下beanDefinitionMap beanDefinitionNames两个变量,除了Spring内置的Bean,还有咱们传进来的Bean,这里的Bean固然就是咱们的配置类了:

image.png
image.png

到这里注册配置类也分析完毕了。

你们能够看到其实到这里,Spring尚未进行扫描,只是实例化了一个工厂,注册了一些内置的Bean和咱们传进去的配置类,真正的大头是在第三行代码:

refresh();

复制代码

为了验证上面的逻辑,能够作个试验:

首先定义了一个Bean,里面有各类回调,其中须要注意下,我在SpringBean的构造方法中打印了studentService,看SpringBean被new的出来的时候,studentService是否被注入了;又在setBeanName中打印了studentService,看此时studentService是否被注入了,以此来验证,Bean是什么时候完成的自动注入的(这个StudentServiceImpl 类的代码就不贴出来了,无非就是一个最普通的Bean):

public class SpringBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, BeanClassLoaderAware {

    public SpringBean() {
        System.out.println("SpringBean构造方法:" + studentService);
        System.out.println("SpringBean构造方法");
    }

    @Autowired
    StudentServiceImpl studentService;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("setBeanClassLoader");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName:" + studentService);
        System.out.println("setBeanName");
    }

    public void initMethod() {
        System.out.println("initMethod");
    }

    public void destroyMethod() {
        System.out.println("destroyMethod");
    }
}

复制代码

再定义一个BeanPostProcessor,在重写的两个方法中进行了判断,若是传进来的beanName是springBean才进行打印:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("springBean")) {
            System.out.println("postProcessBeforeInitialization");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("springBean")) {
            System.out.println("postProcessAfterInitialization");
        }
        return bean;
    }
}

复制代码

定义一个配置类,完成自动扫描,可是SpringBean是手动注册的,而且声明了initMethod和destroyMethod:

@Configuration
@ComponentScan
public class AppConfig {
    @Bean(initMethod = "initMethod",destroyMethod = "destroyMethod")
    public SpringBean springBean() {
        return new SpringBean();
    }
}

复制代码

最后就是启动类了:

public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext =
                new AnnotationConfigApplicationContext(AppConfig.class);
        annotationConfigApplicationContext.destroy();
    }

复制代码

运行结果:

SpringBean构造方法:null
SpringBean构造方法
setBeanName:com.codebear.StudentServiceImpl@31190526
setBeanName
setBeanClassLoader
setBeanFactory
postProcessBeforeInitialization
afterPropertiesSet
initMethod
postProcessAfterInitialization
destroy
destroyMethod

复制代码

能够看到,试验结果和上面分析的彻底一致。

这就是广为流传的Spring生命周期。

也许你在应付面试的时候,是死记硬背这些结论的,如今我带着你找到这些方法,跟我来。

首先咱们来到AnnotationConfigApplicationContext的构造方法:

//根据参数类型能够知道,其实能够传入多个annotatedClasses,可是这种状况出现的比较少
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
        //父类的构造函数里面就是初始化DefaultListableBeanFactory,而且赋值给beanFactory
        //本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner
        //scanner的用处不是很大,它仅仅是在咱们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
        this();
        //把传入的类进行注册,这里有两个状况,
        //传入传统的配置类
        //传入bean(虽然通常没有人会这么作
        //看到后面会知道spring把传统的带上@Configuration的配置类称之为FULL配置类,不带@Configuration的称之为Lite配置类
        //可是咱们这里先把带上@Configuration的配置类称之为传统配置类,不带的称之为普通bean
        register(annotatedClasses);
        //刷新
        refresh();
    }

复制代码

进入refresh方法,refresh方法中有一个finishBeanFactoryInitialization小方法,这个方法是用来实例化懒加载单例Bean的,也就是咱们的Bean都是在这里被建立出来的(固然我这里说的的是绝大部分状况是这样的):

finishBeanFactoryInitialization(beanFactory);

复制代码

咱们再进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.preInstantiateSingletons()方法:

//初始化全部的非懒加载单例
        beanFactory.preInstantiateSingletons();

复制代码

咱们尝试再点进去,这个时候你会发现这是一个接口,好在它只有一个实现类,因此能够咱们来到了他的惟一实现,实现类就是org.springframework.beans.factory.support.DefaultListableBeanFactory,这里面是一个循环,咱们的Bean就是循环被建立出来的,咱们找到其中的getBean方法:

getBean(beanName);

复制代码

这里有一个分支,若是Bean是FactoryBean,如何如何,若是Bean不是FactoryBean如何如何,好在不论是不是FactoryBean,最终仍是会调用getBean方法,因此咱们能够坚决果断的点进去,点进去以后,你会发现,这是一个门面方法,直接调用了doGetBean方法:

return doGetBean(name, null, null, false);

复制代码

再进去,不断的深刻,接近咱们要寻找的东西。 这里面的比较复杂,可是有我在,我能够直接告诉你,下一步咱们要进入哪里,咱们要进入

if (mbd.isSingleton()) {

                    //getSingleton中的第二个参数类型是ObjectFactory<?>,是一个函数式接口,不会马上执行,而是在
                    //getSingleton方法中,调用ObjectFactory的getObject,才会执行createBean
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

复制代码

这里面的createBean方法,再点进去啊,可是又点不进去了,这是接口啊,可是别慌,这个接口又只有一个实现类,因此说 没事,就是干,这个实现类为org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。

这个实现的方法里面又作了不少事情,咱们就不去看了,我就是带着你们找到那几个生命周期的回调到底定义在哪里就OK了。

Object beanInstance = doCreateBean(beanName, mbdToUse, args);//建立bean,核心
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;

复制代码

再继续深刻doCreateBean方法,这个方法又作了一堆一堆的事情,可是值得开心的事情就是 咱们已经找到了咱们要寻找的东西了。

建立实例

首先是建立实例,位于:

instanceWrapper = createBeanInstance(beanName, mbd, args);//建立bean的实例。核心

复制代码

填充属性

其次是填充属性,位于:

populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要

复制代码

在填充属性下面有一行代码:

exposedObject = initializeBean(beanName, exposedObject, mbd);

复制代码

继续深刻进去。

aware系列接口的回调

aware系列接口的回调位于initializeBean中的invokeAwareMethods方法:

invokeAwareMethods(beanName, bean);
private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }

复制代码

BeanPostProcessor的postProcessBeforeInitialization方法

BeanPostProcessor的postProcessBeforeInitialization方法位于initializeBean的

if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

复制代码

afterPropertiesSet init-method

afterPropertiesSet init-method位于initializeBean中的

invokeInitMethods(beanName, wrappedBean, mbd);

复制代码

这里面调用了两个方法,一个是afterPropertiesSet方法,一个是init-method方法:

((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);

复制代码

BeanPostProcessor的postProcessAfterInitialization方法

BeanPostProcessor的postProcessAfterInitialization方法位于initializeBean的

if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

复制代码

固然在实际的开发中,应该没人会去销毁Spring的应用上下文把,因此剩余的两个销毁的回调就不去找了。

这就是广为流传的Spring Bean的生命周期,我也带着你们找到了各类回调和钩子,可是我认为这并不是是Spring Bean完整的生命周期,只是通过简化的,那么我认为的完整的生命周期是如何的呢,请听下回分解。

相关文章
相关标签/搜索