让你不再恐惧Bean生命周期

1,355 阅读6分钟

1.Bean解析

1.1 设置配置类处理器

1.1.1 实例化上下文对象

public AnnotationConfigServletWebServerApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

1.1.2 实例化BeanFactory

AnnotationConfigServletWebServerApplicationContex继承了GenericApplicationContext,在执行构造函数之前会先执行父类构造函数

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

1.1.3 实例化读取器

1.1.1章节会实例化读取器,实例化读取器的同时会往容器中注入一系列的BeanDefinition

1.1.4 注入BeanDefinition

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        // 注入ConfigurationClassPostProcessor,用来处理@Configuration注解标注的配置类
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        // 注入AutowiredAnnotationBeanPostProcessor,用来处理@Autowired、@Value、@Inject注解
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        // 注入CommonAnnotationBeanPostProcessor,用来处理@Resource注解
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    return beanDefs;
}

1.1.5 调用BeanFactoryPostProcessors

上下文刷新的时候会执行invokeBeanFactoryPostProcessors()方法

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// 从容器中获取类型BeanDefinitionRegistryPostProcessor的Bean名称,
        // 在1.1.4章节注入的ConfigurationClassPostProcessor实现了
        // BeanDefinitionRegistryPostProcessor和PriorityOrdered接口,满足条件
        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 创建ConfigurationClassPostProcessor Bean对象
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        // 调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
		// ...省略部分代码
    }
}

1.2 解析配置类

配置类解析入口ConfigurationClassParserdoProcessConfigurationClass方法

1.2.1 处理内部配置类

if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
	// 处理内部@Configuration注解标注的配置类
    processMemberClasses(configClass, sourceClass, filter);
}

1.2.2 处理@ComponentScan注解

// 处理@ComponentScan注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
    sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
    !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
    for (AnnotationAttributes componentScan : componentScans) {
		// 扫描指定路径下@Component注解标注的类并注册为BeanDefinition
        // @Controller、@Service、@Repository、@Configuration都被@Component注解标注,效果一样
        Set<BeanDefinitionHolder> scannedBeanDefinitions =
            this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
		// 遍历BeanDefinition
        for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
            BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
            if (bdCand == null) {
                bdCand = holder.getBeanDefinition();
            }
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                // 解析@Component注解标注的配置类
                parse(bdCand.getBeanClassName(), holder.getBeanName());
            }
        }
    }
}

1.2.3 处理@Import注解

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {
    
    for (SourceClass candidate : importCandidates) {
        // 1.如果@Import注解value指定的类实现ImportSelector接口
        if (candidate.isAssignable(ImportSelector.class)) {
            Class<?> candidateClass = candidate.loadClass();
            // 1.2实例化对象
            ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
                                                                           this.environment, this.resourceLoader, this.registry);
            Predicate<String> selectorFilter = selector.getExclusionFilter();
            if (selectorFilter != null) {
                exclusionFilter = exclusionFilter.or(selectorFilter);
            }
            // 1.3如果实现DeferredImportSelector接口,则进行延迟处理
            // @EnableAutoConfiguration注解引入的AutoConfigurationImportSelector就实现了该接口
            // 用于最后加载spring.factories中的自动配置类
            if (selector instanceof DeferredImportSelector) {
                this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
            }
            // 1.4如果实现的是ImportSelector接口
            else {
                // 1.5调用目标方法
                String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
                // 1.6递归调用
                processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
            }
        }
        // 2.如果实现ImportBeanDefinitionRegistrar接口
        else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
            Class<?> candidateClass = candidate.loadClass();
            // 2.1实例化对象
            ImportBeanDefinitionRegistrar registrar =
                ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
                                                     this.environment, this.resourceLoader, this.registry);
            // 2.2将实例化对象存储在当前配置类中(后续会用到)
            configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
        }
        else {
            // 3. 没有实现任何接口,当做普通配置类进行解析
            // 该普通配置类由当前配置类引入(后续会用到)
            this.importStack.registerImport(
                currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
            processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
        }
    }
}

1.2.4 处理@Bean注解

// 解析当前配置类中含有@Bean注解的方法,组装成MethodMetadata
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
    // 根据MethodMetadata组装成BeanMethod放入当前配置类中(后续会用到)
    configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

1.2.5 处理@EnableAutoConfiguration注解

所有的配置类解析完成后都会放入map中

this.configurationClasses.put(configClass, configClass);

@EnableAutoConfiguration引入了AutoConfigurationImportSelector,AutoConfigurationImportSelector又实现了DeferredImportSelector接口,根据1.2.3章节的分析可得出AutoConfigurationImportSelector引入的自动配置类会在最后进行解析,解析完成后加入configurationClasses容器中

1.2.6 加载BeanDefinition

除了1.2.2章节@ComponentScan注解扫描的配置类生成BeanDefinition注入容器,@Import@Bean@EnableAutoConfiguration都没有生成BeanDefinition注入容器

private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
	// 如果当前配置类是被导入的,生成BeanDefinition并注入容器中,对应1.2.3章节中的第三部分
    if (configClass.isImported()) {
        registerBeanDefinitionForImportedConfigurationClass(configClass);
    }
    
    // 获取当前配置类中的BeanMethod,生成BeanDefinition并注入容器中,对应1.2.4章节
    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
        loadBeanDefinitionsForBeanMethod(beanMethod);
    }

    // 获取当前配置类中ImportBeanDefinitionRegistrar生成BeanDefinition并注入容器中,对应1.2.3章节中的第二部分
    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

1.2.7 注入容器的几种方式

  • @Component注解标注
  • @Import引入
  • @Bean注解标注
  • spring.factories中定义org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx

2.Bean创建

解析完配置类生成BeanDefinition并注入容器后,接下来就是实例化容器中的BeanDefinition

2.1 Bean实例化

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // 1.使用提供的Supplier进行实例化
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 2.@Bean注解标注,通过反射方式调用目标方法进行实例化
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 3.调用构造函数进行实例化
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        // 4.调用构造函数进行实例化
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // 5.调用无参构造函数进行实例化
    return instantiateBean(beanName, mbd);
}

2.2 填充Bean

实例化对象之后需要对注入的属性进行填充,如@Value、@Autowired、@Inject注解标注的属性或方法

2.2.1 指定填充类型

public AutowiredAnnotationBeanPostProcessor() {
    // 1.设置@Autowired类型
    this.autowiredAnnotationTypes.add(Autowired.class);
    // 2.设置@Value类型
    this.autowiredAnnotationTypes.add(Value.class);
    try {
        // 3.兼容@Inject类型
        this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                                          ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
    }
    catch (ClassNotFoundException ex) {
    }
}

2.2.2 构建元数据

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
		// 1. 遍历当前类被@Value、@Autowired、@Inject注解标注的属性,构建AutowiredFieldElement
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
                // 2.不能被static修饰
                if (Modifier.isStatic(field.getModifiers())) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static fields: " + field);
                    }
                    return;
                }
                boolean required = determineRequiredStatus(ann);
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });

        // 3.遍历当前类被@Value、@Autowired、@Inject注解标注的方法,构建AutowiredMethodElement
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                // 4.不能被static修饰
                if (Modifier.isStatic(method.getModifiers())) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static methods: " + method);
                    }
                    return;
                }
                if (method.getParameterCount() == 0) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation should only be used on methods with parameters: " +
                                    method);
                    }
                }
                boolean required = determineRequiredStatus(ann);
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

2.2.3 注入填充

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
        (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        // 1.遍历2.2.2章节构建的元数据
        for (InjectedElement element : elementsToIterate) {
            // 2.如果是@Value注解标注,则根据value属性值从Environment中获取对应的配置
            // 3.如果是@Autowired注解标注,则从容器中获取对应的Bean进行注入
            element.inject(target, beanName, pvs);
        }
    }
}

2.3 初始化Bean

2.3.1 Aware处理

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        // 1.当前Bean实现了BeanNameAware接口,则回调setBeanName()方法设置Bean名称
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        // 2.当前Bean实现了BeanClassLoaderAware接口,则回调setBeanClassLoader()方法设置ClassLoader
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        // 3. 当前Bean实现了BeanFactoryAware接口,则回调setBeanFactory()方法设置BeanFactory
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

ApplicationContextAwareProcessor前置处理

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationStartupAware) {
        ((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

这里就可以搞明白为什么实现xxxAware接口,就可以得到某种能力的原因了

2.3.2 BeanPostProcessor前置处理

遍历容器中所有的BeanPostProcessor并调用其postProcessBeforeInitialization()方法

@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;
}

2.3.3 @PostConstruct注解处理

CommonAnnotationBeanPostProcessor实现了BeanPostProcessor接口,因此也会调用BeanPostProcessorpostProcessBeforeInitialization()方法,用来处理@PostConstruct注解

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    setInitAnnotationType(PostConstruct.class);
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");
}

2.3.4 InitializingBean处理

Bean实现InitializingBean接口,则调用afterPropertiesSet()实现方法进行初始化操作

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
		((InitializingBean) bean).afterPropertiesSet();
    }
}

2.3.5 @Bean注解initMethod处理

if (mbd != null && bean.getClass() != NullBean.class) {
    String initMethodName = mbd.getInitMethodName();
    if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.isExternallyManagedInitMethod(initMethodName)) {
        // 在Bean中查找initMethod指定的初始化方法并进行回调
        invokeCustomInitMethod(beanName, bean, mbd);
    }
}

2.3.6 BeanPostProcessor后置处理

@Override
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;
}

3. Bean生命周期总结

  • 解析生成BeanDefinition注入容器
  • 创建Bean
  • 填充@Value@Autowired数据
  • 回调Aware接口实现方法
  • 执行BeanPostProcessor前置处理
  • 回调InitializingBean接口实现方法
  • 调用@Bean注解的initMethod属性指定的方法
  • 执行BeanPostProcessor后置处理