当前位置: 首页 > article >正文

Spring源码分析のBean创建流程(下)

文章目录

  • 前言
  • 一、createBean
    • 1.1、resolveBeanClass
    • 1.2、resolveBeforeInstantiation
  • 二、doCreateBean
    • 2.1、createBeanInstance
    • 2.2、applyMergedBeanDefinitionPostProcessors
    • 2.3、initializeBean
    • 2.4 registerDisposableBeanIfNecessary
  • 总结


前言

   在doGetBean方法中,如果即将获取的bean不存在,无论是何种作用域的bean,最终都会调用createBean方法去创建bean。createBean方法是bean创建流程中的重要方法。

一、createBean

   createBean有三个参数,而主要参数:参数一是bean的名称,而参数二是合并后的bean定义。在方法中主要完成了:

  1. 将beanName转换为bean的class对象,并且赋值给bean定义的BeanClass属性。
  2. 处理当前 Bean 配置了方法重写的情况。
  3. bean实例化前的处理
  4. 在doCreateBean中进行bean实例化等一系列操作。
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		//1.1、resolveBeanClass将bean定义和bean的名称传入resolveBeanClass,得到bean的class对象
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			//将bean定义中的beanClass属性设置为加载后的类
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			//处理当前 Bean 配置了方法重写(可能是通过 XML 配置、注解或代码配置)的情况
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//1.2、resolveBeforeInstantiation bean实例化前的处理
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//实例化bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			//返回bean的实例
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

1.1、resolveBeanClass

  resolveBeanClass方法是利用jvm去加载类,如果发现当前bean定义的beanClass属性已经是class类型,就直接返回,不去重复加载。
  在doResolveBeanClass方法中,主要考虑到了AOP的场景,以及类名是表达式的场景。
  类名是动态表达式的案例:
  applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 定义动态类名 -->
    <bean id="dynamicClass" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties" value="classpath:dynamic.properties"/>
    </bean>

    <!-- 使用 SpEL 表达式动态解析类名 -->
    <bean id="myBean" class="#{ T(java.lang.Class).forName('${dynamic.class.name}') }"/>
</beans>

  dynamic.properties

# dynamic.properties
dynamic.class.name=com.example.MyDynamicClass

package com.example;

public class MyDynamicClass {
    public void greet() {
        System.out.println("Hello from MyDynamicClass!");
    }
}

  resolveBeanClass&doResolveBeanClass详解:

	@Nullable
	protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
			throws CannotLoadBeanClassException {

		try {
			//如果当前bean定义的beanClass属性已经是class类型,就直接返回,不去重复加载
			if (mbd.hasBeanClass()) {
				return mbd.getBeanClass();
			}
			//无论是否开启了安全检查,最终都会去调用doResolveBeanClass方法
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
						() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
			}
			else {
				return doResolveBeanClass(mbd, typesToMatch);
			}
		}
		catch (PrivilegedActionException pae) {
			ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (ClassNotFoundException ex) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (LinkageError err) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
		}
	}


	/**
	*	真正去加载类的方法
	*	参数一:合并后的bean定义
	**/
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {

    // 获取默认的类加载器,用于加载 Bean 类。
    ClassLoader beanClassLoader = getBeanClassLoader();

    // 将动态加载器初始化为默认的 Bean 类加载器
    ClassLoader dynamicLoader = beanClassLoader;

    // 记录是否需要重新解析的标志,默认为 false
    boolean freshResolve = false;

    // 如果传入的 typesToMatch 不为空,表示需要进行类型检查(AOP的场景)
    if (!ObjectUtils.isEmpty(typesToMatch)) {
        ClassLoader tempClassLoader = getTempClassLoader();
        if (tempClassLoader != null) {
            dynamicLoader = tempClassLoader;
            freshResolve = true;
            if (tempClassLoader instanceof DecoratingClassLoader) {
                DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                for (Class<?> typeToMatch : typesToMatch) {
                    dcl.excludeClass(typeToMatch.getName());
                }
            }
        }
    }

    // 获取 Bean 定义中的类名
    String className = mbd.getBeanClassName();

    // 如果类名不为空
    if (className != null) {
        // 如果类名是一个表达式,可能会被解析成实际的类名
        Object evaluated = evaluateBeanDefinitionString(className, mbd);
        // 类名与原始类名不同,表示类名是动态解析出来的
        if (!className.equals(evaluated)) {
            // 结果是一个 Class 对象
            if (evaluated instanceof Class) {
                // 直接返回 Class 对象
                return (Class<?>) evaluated;
            }
            // 如果结果是一个字符串
            else if (evaluated instanceof String) {
                // 将动态解析后的类名赋值给 className
                className = (String) evaluated;
                // 标记需要重新解析
                freshResolve = true;
            }
            else {
                throw new IllegalStateException("Invalid class name expression result: " + evaluated);
            }
        }

        // 如果需要重新解析
        if (freshResolve) {
            // 如果使用临时类加载器进行解析,则提前返回,不将结果缓存到 Bean 定义中
            if (dynamicLoader != null) {
                try {
                    // 尝试用动态加载器加载该类
                    return dynamicLoader.loadClass(className);
                } catch (ClassNotFoundException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                    }
                }
            }
            // 使用默认的类加载器加载类并返回
            return ClassUtils.forName(className, dynamicLoader);
        }
    }

    // 如果没有找到类名,或者没有重新解析,最终会使用Class.forName加载类
    return mbd.resolveBeanClass(beanClassLoader);
}

在这里插入图片描述一般场景下通过org.springframework.util.ClassUtils#forName的Class.forName方法加载类

1.2、resolveBeforeInstantiation

  在resolveBeforeInstantiation方法中,重点会判断目标bean是否实现了InstantiationAwareBeanPostProcessor接口,当一个类实现了InstantiationAwareBeanPostProcessor接口时,可以选择重写其中的postProcessAfterInstantiation(实例化后)、postProcessBeforeInstantiation(实例化前)方法,以及其父类BeanPostProcessorpostProcessAfterInitialization(初始化后)、postProcessBeforeInitialization(初始化前)的方法(接口中有default关键字):

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    /**
     * bean实例化前的处理
     * 可以在方法中利用反射直接创建对象
     * @param beanClass the class of the bean to be instantiated
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object bean = null;
        try {
            bean = beanClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return bean;
    }

    /**
     * hasInstantiationAwareBeanPostProcessors() 的判断依据
     * @param bean the bean instance created, with properties not having been set yet
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return beanName.equals("orderService");
    }

    /**
     * bean初始化前的处理
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    /**
     * bean初始化后的处理
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }
}

  可以在applyBeanPostProcessorsBeforeInstantiation方法中,通过反射创建对象。这样的对象,生命周期就不归Spring容器去统一管理了,直接跳转到初始化后的方法,然后返回bean。

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			//有自定义的bean实现了InstantiationAwareBeanPostProcessor接口
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//调用实例化前的方法,在该方法中,可以自己通过反射创建对象
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					//如果自己通过反射创建了对象,直接执行初始化后的方法
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

二、doCreateBean

  在doCreateBean方法中,主要做了:

  1. 通过反射创建一个bean的实例,并且包装成BeanWrapper。
  2. 遍历所有实现了MergedBeanDefinitionPostProcessor接口的类,执行其中的postProcessMergedBeanDefinition方法(在创建了实例后,修改bean定义)
  3. 进行bean的属性填充。
  4. 进行bean的初始化操作。
  5. 确保在Spring容器销毁Bean时,能够正确地调用其销毁方法。
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		//定义一个BeanWrapper 对象
		BeanWrapper instanceWrapper = null;
		//如果当前需要实例化的bean是单例的
		if (mbd.isSingleton()) {
			//尝试从缓存中获取
			//k:bean的名称 value 对应的BeanWrapper 对象
			//private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		//缓存中获取不到
		if (instanceWrapper == null) {
			//2.1、createBeanInstance 创建一个bean的实例,并且包装成BeanWrapper 
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//获取创建完成的bean的实例
		Object bean = instanceWrapper.getWrappedInstance();
		//得到bean实例的class 例:class org.ragdollcat.OrderService
		Class<?> beanType = instanceWrapper.getWrappedClass();
		//当前的bean 不是 nullbean
		if (beanType != NullBean.class) {
			//设置bean定义的解析目标类型
			mbd.resolvedTargetType = beanType;
		}

		//允许后处理器修改合并的 bean 定义。
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//2.2 applyMergedBeanDefinitionPostProcessors 
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//这一段和解决循环依赖有关 单独开一篇分析
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//进行bean的属性填充 单独开一篇分析
			populateBean(beanName, mbd, instanceWrapper);
			//2.3、initializeBean 进行bean的初始化
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		//解决循环依赖 单独开一篇说明
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			//2.4 registerDisposableBeanIfNecessary 用于处理可能存在的bean销毁回调
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

2.1、createBeanInstance

  这段代码根据不同的条件(是否有工厂方法、是否有构造函数、是否需要自动装配等)决定使用何种方式来实例化一个 Bean。最终将结果包装成BeanWrapper返回。

  • 如果定义了工厂方法,则通过工厂方法来创建 Bean。
  • 如果定义了 Supplier,则通过该提供者获取 Bean 实例。
  • 如果 Bean 需要通过构造函数进行自动装配,则选择合适的构造函数。
  • 最常见的情况:如果没有特殊的要求,直接使用无参构造函数创建 Bean。
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//这一步会看mbd.hasBeanClass()是否有值
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		//检查Bean类是否是公共的,若不是则抛出异常(除非允许非公共访问)
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		//获取Bean定义中的实例提供者
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			//如果定义了实例提供者,直接通过实例提供者获取Bean实例(通常用于通过 Lambda 或其他外部工厂方法提供 Bean 实例的情况。)
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		//如果定义了工厂方法,则使用工厂方法来实例化Bean
		//使用 @Bean 注解的情况,或者显式定义工厂方法的场景。
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 如果 args 为空(即没有显式传入构造函数参数)
		// 并且 Bean 的构造函数或工厂方法已经解析过(resolvedConstructorOrFactoryMethod != null),则直接根据解析结果创建 Bean 实例。
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				 检查Bean定义中是否已经解析了构造函数或者工厂方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				// 如果需要自动装配,则调用autowireConstructor来处理自动装配
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
			  // 如果不需要自动装配,直接使用无参构造器创建Bean
				return instantiateBean(beanName, mbd);
			}
		}

		//进行构造方法推论
		//如果 Bean 需要通过构造函数进行自动装配(例如通过 @Autowired 注解自动注入构造函数参数),则会进入这个分支。
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 某些情况下,Bean 定义中可能指定了首选的构造函数,这时候就会选择这些构造函数来创建 Bean。
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// 最常见的情况,Bean 没有复杂的构造函数或特殊要求时,会通过无参构造函数创建实例。
		return instantiateBean(beanName, mbd);
	}

在这里插入图片描述instantiateBean 利用反射创建对象

补充:三种情况案例

  1. 使用工厂方法创建 Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Person person() {
        return new Person("John", 30);
    }
}

  1. 使用实例提供者获取 Bean 实例:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.function.Supplier;

@Configuration
public class AppConfig {

    // 使用 Supplier 提供一个 Person 实例
    @Bean
    public Person person() {
        Supplier<Person> personSupplier = () -> new Person("Tom", 40);
        return personSupplier.get();
    }
}
  1. 使用自动装配构造函数创建 Bean:
public class Person {

    private String name;
    private int age;
    private Address address;

    // 通过构造函数自动装配
    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // getter 和 setter 省略
}

public class Address {
    private String city;
    private String street;

    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }

    // getter 和 setter 省略
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    // 通过构造函数自动装配 Address 和 Person
    @Bean
    public Person person(Address address) {
        return new Person("Jack", 35, address);
    }

    // Address Bean
    @Bean
    public Address address() {
        return new Address("New York", "5th Avenue");
    }
}

2.2、applyMergedBeanDefinitionPostProcessors

  applyMergedBeanDefinitionPostProcessors方法主要的作用:遍历所有实现了MergedBeanDefinitionPostProcessor接口的类,执行其中的postProcessMergedBeanDefinition方法:

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     		//允许在bean创建实例后,对bean定义再次进行修改   
    }
}
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		//遍历所有实现了MergedBeanDefinitionPostProcessor接口的类,执行其中的postProcessMergedBeanDefinition方法
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}

	BeanPostProcessorCache getBeanPostProcessorCache() {
		BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
		if (bpCache == null) {
			bpCache = new BeanPostProcessorCache();
			//下面的各种BeanPostProcessor都是BeanPostProcessor 的子类
			for (BeanPostProcessor bp : this.beanPostProcessors) {
				//该类型的 BeanPostProcessor 用于在 Bean 实例化时进行处理,通常是在 Bean 的实例化前后做一些操作,比如属性填充、依赖注入等。
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
					//是 InstantiationAwareBeanPostProcessor 的子接口
					if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
						bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
					}
				}
				//该接口用于处理 Bean 销毁时的回调。实现该接口的 BeanPostProcessor 可以在 Bean 销毁时做一些清理工作。
				if (bp instanceof DestructionAwareBeanPostProcessor) {
					bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
				}
				//用于处理合并后的 Bean 定义的后处理器。合并后的 Bean 定义通常是在多个配置或多个容器中对 Bean 的定义进行合并时使用的。
				if (bp instanceof MergedBeanDefinitionPostProcessor) {
					bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
				}
			}
			this.beanPostProcessorCache = bpCache;
		}
		//最后返回构建好的 BeanPostProcessorCache,该缓存包含了按照不同类型分类的 BeanPostProcessor。
		return bpCache;
	}

2.3、initializeBean

  initializeBean 是进行bean的初始化操作:

  • 调用 Aware 接口方法:首先根据是否存在 SecurityManager,安全地调用 bean 的 Aware 接口方法。
  • 应用初始化前的 BeanPostProcessor:在 bean 初始化前,执行所有的 BeanPostProcessor,对 bean 进行增强或修改。
  • 执行初始化方法:调用 InitializingBeanafterPropertiesSet() 方法以及init-method配置的自定义初始化方法。
  • 应用初始化后的 BeanPostProcessor:在初始化后,执行所有的 BeanPostProcessor,对 bean 进行进一步的增强。
  • 返回处理后的 bean:返回可能经过修改或增强的最终 bean 实例。
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		//无论是否安全检查,执行各种Aware回调
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		//当前的 bean 不是由框架内部合成或创建的(即用户定义的正常 bean)
		if (mbd == null || !mbd.isSynthetic()) {
			//执行bean初始化前的操作
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//调用自定义的初始化方法,以及实现了 InitializingBean 接口的afterPropertiesSet方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//执行bean初始化后的操作
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		//最终返回的是经过所有处理(初始化前、初始化、初始化后)后的 wrappedBean 对象。这个对象可能经过了一些增强或修改,通常是通过 AOP 等方式。
		return wrappedBean;
	}

2.4 registerDisposableBeanIfNecessary

  registerDisposableBeanIfNecessary 确保在Spring容器销毁Bean时,能够正确地调用其销毁方法。

	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		//1.只有单例bean才需要由spring容器去管理销毁操作
		//2.当前Bean是否需要销毁(即它是否实现了 DisposableBean 接口或者有自定义的销毁方法)
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// Register a DisposableBean implementation that performs all destruction
				// work for the given bean: DestructionAwareBeanPostProcessors,
				// DisposableBean interface, custom destroy method.
				registerDisposableBean(beanName, new DisposableBeanAdapter(
						bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
			}
			//其他作用范围(非单例非多例)
			else {
				// A bean with a custom scope...
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
				}
				scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
						bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
			}
		}
	}

总结

  在解析xml或注解扫描将对应的bean转换为bean定义后,剩余的步骤以及扩展点:

  1. 将beanName转换为bean的class对象(通过jvm加载类得到class)
  2. 处理当前 bean 配置了方法重写的情况
  3. 通过反射将bean 实例化,并且包装成BeanWrapper。
    • 如果定义了工厂方法,则通过工厂方法来创建 Bean。
    • 如果定义了 Supplier,则通过该提供者获取 Bean 实例。
    • 如果 Bean 需要通过构造函数进行自动装配,则选择合适的构造函数。
    • 最常见的情况:如果没有特殊的要求,直接使用无参构造函数创建 Bean。
  4. 遍历所有实现了MergedBeanDefinitionPostProcessor接口的类,执行其中的postProcessMergedBeanDefinition方法(在创建了实例后,修改bean定义)
  5. 进行bean的属性填充
    - 自动装配:Spring 会根据配置(如 @Autowired 注解或 XML 配置的自动装配策略)将依赖注入到 Bean 中。如果未明确配置注入策略,Spring 会默认使用按类型自动装配。
    - 属性填充的优先级:如果 Bean 中有多个候选依赖项,Spring 会根据类型和名称来决定注入的优先级,避免出现多个匹配时的冲突。
  6. 进行bean的初始化操作
    • 调用 Aware 接口方法:首先根据是否存在 SecurityManager,安全地调用 bean 的 Aware 接口方法。
    • 应用初始化前的 BeanPostProcessor:在 bean 初始化前,执行所有的 BeanPostProcessor,对 bean 进行增强或修改。
    • 执行初始化方法:调用 InitializingBeanafterPropertiesSet() 方法以及init-method配置的自定义初始化方法。
    • 应用初始化后的 BeanPostProcessor:在初始化后,执行所有的 BeanPostProcessor,对 bean 进行进一步的增强。
    • 返回处理后的 bean:返回可能经过修改或增强的最终 bean 实例。
  7. 确保在Spring容器销毁Bean时,能够正确地调用其销毁方法。
    - 在容器关闭或销毁时,Spring 会检查是否配置了销毁方法(如@PreDestroy注解或 destroy-method)。如果配置了销毁方法,Spring 会在销毁 Bean 时自动调用该方法。
    - 销毁操作通常包括关闭资源、清理状态、释放锁等操作,确保容器在销毁时不会漏掉重要的资源释放。
  8. 果 Bean 被 AOP 代理(如通过 @Transactional 注解),Spring 会在实例化后对 Bean 进行增强。所有的增强逻辑会通过代理对象进行,而实际的业务逻辑通常在原始 Bean 中。

http://www.kler.cn/a/553612.html

相关文章:

  • 科普:Docker run的相关事项
  • Vue前端开发-Vant之Image组件
  • 【基于SprintBoot+Mybatis+Mysql】电脑商城项目之设置默认收货地址及删除收货地址
  • React 渲染 Flash 接口数据
  • AI技术生成【参考】
  • K8s学习总结
  • 智慧园区安全调度的重要性
  • Oppo手机投屏到Windows的两个方法,Windows系统自带投屏的替补!
  • 代码随想录算法【Day50】
  • 并发和多线程
  • 提升信息检索准确性和效率的搜索技巧
  • Windows桌面系统管理7:国产操作系统与Linux操作系统
  • 深度学习-119-Text2SQL之实现的三种技术途径
  • python 快速实现链接转 word 文档
  • 【面试题】redis大key问题怎么解决?(key访问的次数比较多,key存的数据比较大)
  • 2.2 反向传播:神经网络如何“学习“?
  • 基于python深度学习遥感影像地物分类与目标识别、分割
  • vue 接口传formdata
  • Redis初识
  • 英莱科技激光视觉焊缝跟踪系统全新PF系列新品发布,三大技术融合,强悍来袭