• Spring 创建 Bean 全过程


    springboot 版本:2.7.0,不同的 spring 版本的容器刷新方法的位置会有不同,但大致都是一样的。

    首先创建一个简单的 SpringBoot 项目,创建一个 Bean 并交给容器管理,后续 debug 这个 Bean 的创建步骤来了解 Spring 创建 Bean 的全过程。

    创建 IOC 容器

    进入 SpringApplication.run() 方法,进而跳到如下方法:

    /**
    	 * Run the Spring application, creating and refreshing a new
    	 * {@link ApplicationContext}.
    	 * @param args the application arguments (usually passed from a Java main method)
    	 * @return a running {@link ApplicationContext}
    	 */
    	public ConfigurableApplicationContext run(String... args) {
    		long startTime = System.nanoTime();
    		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    		ConfigurableApplicationContext context = null;
    		configureHeadlessProperty();
    		SpringApplicationRunListeners listeners = getRunListeners(args);
    		listeners.starting(bootstrapContext, this.mainApplicationClass);
    		try {
    			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
    			configureIgnoreBeanInfo(environment);
    			Banner printedBanner = printBanner(environment);
                // 创建 IOC 容器,即 Spring 上下文
    			context = createApplicationContext();
    			context.setApplicationStartup(this.applicationStartup);
    			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
                // 刷新容器
    			refreshContext(context);
    			afterRefresh(context, applicationArguments);
    			Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
    			if (this.logStartupInfo) {
    				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
    			}
    			listeners.started(context, timeTakenToStartup);
    			callRunners(context, applicationArguments);
    		}
    		catch (Throwable ex) {
    			handleRunFailure(context, ex, listeners);
    			throw new IllegalStateException(ex);
    		}
    		try {
    			Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
    			listeners.ready(context, timeTakenToReady);
    		}
    		catch (Throwable ex) {
    			handleRunFailure(context, ex, null);
    			throw new IllegalStateException(ex);
    		}
    		return context;
    	}
    

    context = createApplicationContext(); 方法用于创建 IOC 容器,ApplicationContext 接口有很多的实现类,该方法用来确定生成的具体实现类是哪一个。

    进入该方法后,发现它用到了 SpringApplication 类的两个成员变量。

    • private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;

    ApplicationContextFactory 是一个函数式接口,接口中的方法是 ConfigurableApplicationContext create(WebApplicationType webApplicationType);,并且定义了一个名为 DEFAULT 的默认实现,而 SpringApplication 用的就是这个默认实现。

    阅读类上方的文档可知该接口是一个策略接口,用于 SpringApplication 来创建一个 ConfigurableApplicationContext。

    /**
     * Strategy interface for creating the {@link ConfigurableApplicationContext} used by a
     * {@link SpringApplication}. Created contexts should be returned in their default form,
     * with the {@code SpringApplication} responsible for configuring and refreshing the
     * context.
     *
     * @author Andy Wilkinson
     * @author Phillip Webb
     * @since 2.4.0
     */
    @FunctionalInterface
    public interface ApplicationContextFactory {
    
    	/**
    	 * A default {@link ApplicationContextFactory} implementation that will create an
    	 * appropriate context for the {@link WebApplicationType}.
    	 */
    	ApplicationContextFactory DEFAULT = (webApplicationType) -> {
    		try {
    			for (ApplicationContextFactory candidate : SpringFactoriesLoader
    					.loadFactories(ApplicationContextFactory.class, ApplicationContextFactory.class.getClassLoader())) {
    				ConfigurableApplicationContext context = candidate.create(webApplicationType);
    				if (context != null) {
    					return context;
    				}
    			}
    			return new AnnotationConfigApplicationContext();
    		}
    		catch (Exception ex) {
    			throw new IllegalStateException("Unable create a default ApplicationContext instance, "
    					+ "you may need a custom ApplicationContextFactory", ex);
    		}
    	};
    
    	/**
    	 * Creates the {@link ConfigurableApplicationContext application context} for a
    	 * {@link SpringApplication}, respecting the given {@code webApplicationType}.
    	 * @param webApplicationType the web application type
    	 * @return the newly created application context
    	 */
    	ConfigurableApplicationContext create(WebApplicationType webApplicationType);
    
    	/**
    	 * Creates an {@code ApplicationContextFactory} that will create contexts by
    	 * instantiating the given {@code contextClass} via its primary constructor.
    	 * @param contextClass the context class
    	 * @return the factory that will instantiate the context class
    	 * @see BeanUtils#instantiateClass(Class)
    	 */
    	static ApplicationContextFactory ofContextClass(Class<? extends ConfigurableApplicationContext> contextClass) {
    		return of(() -> BeanUtils.instantiateClass(contextClass));
    	}
    
    	/**
    	 * Creates an {@code ApplicationContextFactory} that will create contexts by calling
    	 * the given {@link Supplier}.
    	 * @param supplier the context supplier, for example
    	 * {@code AnnotationConfigApplicationContext::new}
    	 * @return the factory that will instantiate the context class
    	 */
    	static ApplicationContextFactory of(Supplier<ConfigurableApplicationContext> supplier) {
    		return (webApplicationType) -> supplier.get();
    	}
    
    }
    
    • private WebApplicationType webApplicationType;

    WebApplicationType 是一个枚举类,它用来确定创建的 web application 的类型。这里它的类型为 NONE。

    /**
     * An enumeration of possible types of web application.
     *
     * @author Andy Wilkinson
     * @author Brian Clozel
     * @since 2.0.0
     */
    public enum WebApplicationType {
    
    	/**
    	 * The application should not run as a web application and should not start an
    	 * embedded web server.
    	 */
    	NONE,
    
    	/**
    	 * The application should run as a servlet-based web application and should start an
    	 * embedded servlet web server.
    	 */
    	SERVLET,
    
    	/**
    	 * The application should run as a reactive web application and should start an
    	 * embedded reactive web server.
    	 */
    	REACTIVE;
    
    	private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
    			"org.springframework.web.context.ConfigurableWebApplicationContext" };
    
    	private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
    
    	private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
    
    	private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
    
    	private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
    
    	private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
    
    	static WebApplicationType deduceFromClasspath() {
    		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
    				&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
    			return WebApplicationType.REACTIVE;
    		}
    		for (String className : SERVLET_INDICATOR_CLASSES) {
    			if (!ClassUtils.isPresent(className, null)) {
    				return WebApplicationType.NONE;
    			}
    		}
    		return WebApplicationType.SERVLET;
    	}
    
    	static WebApplicationType deduceFromApplicationContext(Class<?> applicationContextClass) {
    		if (isAssignable(SERVLET_APPLICATION_CONTEXT_CLASS, applicationContextClass)) {
    			return WebApplicationType.SERVLET;
    		}
    		if (isAssignable(REACTIVE_APPLICATION_CONTEXT_CLASS, applicationContextClass)) {
    			return WebApplicationType.REACTIVE;
    		}
    		return WebApplicationType.NONE;
    	}
    
    	private static boolean isAssignable(String target, Class<?> type) {
    		try {
    			return ClassUtils.resolveClassName(target, null).isAssignableFrom(type);
    		}
    		catch (Throwable ex) {
    			return false;
    		}
    	}
    
    }
    

    在这里插入图片描述

    由此可知最终会进入到这个方法。

    /**
    	 * A default {@link ApplicationContextFactory} implementation that will create an
    	 * appropriate context for the {@link WebApplicationType}.
    	 */
    	ApplicationContextFactory DEFAULT = (webApplicationType) -> {
    		try {
    			for (ApplicationContextFactory candidate : SpringFactoriesLoader
    					.loadFactories(ApplicationContextFactory.class, ApplicationContextFactory.class.getClassLoader())) {
    				ConfigurableApplicationContext context = candidate.create(webApplicationType);
    				if (context != null) {
    					return context;
    				}
    			}
    			return new AnnotationConfigApplicationContext();
    		}
    		catch (Exception ex) {
    			throw new IllegalStateException("Unable create a default ApplicationContext instance, "
    					+ "you may need a custom ApplicationContextFactory", ex);
    		}
    	};
    

    简单分析代码可知该方法会遍历 IOC 容器工厂类来创建容器,如果创建成功则返回,如果没有默认创建 AnnotationConfigApplicationContext();,由 debug 结果可知这里创建的就是默认的 IOC 容器。

    AnnotationConfigApplicationContext

    刷新容器

    refreshContext(context); 方法用于刷新 IOC 容器,创建 Bean 的逻辑代码都在这个方法里面。debug 该方法并跳到真正创建 bean 的方法中。

    1. AbstractApplicationContext#refresh()
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
    
            // Prepare this context for refreshing.
            prepareRefresh();
    
            // Tell the subclass to refresh the internal bean factory.
            // 创建 bean 工厂,它用来管理所有的 bean
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // Prepare the bean factory for use in this context.
            // 使用 IOC 容器来预初始化 bean 工厂,如 添加一些必要的 bean 和 bean后置处理器
            prepareBeanFactory(beanFactory);
    
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
    
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // Invoke factory processors registered as beans in the context.
                // 调用 bean 工厂的后置处理器
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // Register bean processors that intercept bean creation.
                // 注册一些必要的 bean 后置处理器,如 aop 的后置处理器等
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
    
                // Initialize message source for this context.
                initMessageSource();
    
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
    
                // Initialize other special beans in specific context subclasses.
                onRefresh();
    
                // Check for listener beans and register them.
                registerListeners();
    
                // Instantiate all remaining (non-lazy-init) singletons.
                // 实例化所有非懒加载的单例 bean
                finishBeanFactoryInitialization(beanFactory);
    
                // Last step: publish corresponding event.
                finishRefresh();
            }
    
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                }
    
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
    
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
                contextRefresh.end();
            }
        }
    }
    
    1. AbstractApplicationContext#finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
    /**
    	 * Finish the initialization of this context's bean factory,
    	 * initializing all remaining singleton beans.
    	 */
    	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    		// Initialize conversion service for this context.
    		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
    				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
    			beanFactory.setConversionService(
    					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    		}
    
    		// Register a default embedded value resolver if no BeanFactoryPostProcessor
    		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
    		// at this point, primarily for resolution in annotation attribute values.
    		if (!beanFactory.hasEmbeddedValueResolver()) {
    			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    		}
    
    		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    		for (String weaverAwareName : weaverAwareNames) {
    			getBean(weaverAwareName);
    		}
    
    		// Stop using the temporary ClassLoader for type matching.
    		beanFactory.setTempClassLoader(null);
    
    		// Allow for caching all bean definition metadata, not expecting further changes.
    		beanFactory.freezeConfiguration();
    
    		// Instantiate all remaining (non-lazy-init) singletons.
    		beanFactory.preInstantiateSingletons();
    	}
    
    1. DefaultListableBeanFactory#preInstantiateSingletons()

    该方法先获取所有 bean 的名称并遍历,然后调用 getBean(beanName); 方法实例化。

    @Override
    	public void preInstantiateSingletons() throws BeansException {
    		if (logger.isTraceEnabled()) {
    			logger.trace("Pre-instantiating singletons in " + this);
    		}
    
    		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
    		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    		// Trigger initialization of all non-lazy singleton beans...
    		for (String beanName : beanNames) {
    			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    				if (isFactoryBean(beanName)) {
    					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    					if (bean instanceof FactoryBean) {
    						FactoryBean<?> factory = (FactoryBean<?>) bean;
    						boolean isEagerInit;
    						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    							isEagerInit = AccessController.doPrivileged(
    									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
    									getAccessControlContext());
    						}
    						else {
    							isEagerInit = (factory instanceof SmartFactoryBean &&
    									((SmartFactoryBean<?>) factory).isEagerInit());
    						}
    						if (isEagerInit) {
    							getBean(beanName);
    						}
    					}
    				}
    				else {
    					getBean(beanName);
    				}
    			}
    		}
    
    		// Trigger post-initialization callback for all applicable beans...
    		for (String beanName : beanNames) {
    			Object singletonInstance = getSingleton(beanName);
    			if (singletonInstance instanceof SmartInitializingSingleton) {
    				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
    						.tag("beanName", beanName);
    				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    				if (System.getSecurityManager() != null) {
    					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    						smartSingleton.afterSingletonsInstantiated();
    						return null;
    					}, getAccessControlContext());
    				}
    				else {
    					smartSingleton.afterSingletonsInstantiated();
    				}
    				smartInitialize.end();
    			}
    		}
    	}
    

    这里我们可以在循环的第一行打一个断点,然后 debug 放行循环直到 beanName 是我们自定义的 Bean,开始实例化自定义 Bean。

    在这里插入图片描述

    1. AbstractBeanFactory#getBean(String name)
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
    
    1. AbstractBeanFactory#doGetBean(name, null, null, false)
    /**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * @param name the name of the bean to retrieve
    	 * @param requiredType the required type of the bean to retrieve
    	 * @param args arguments to use when creating a bean instance using explicit arguments
    	 * (only applied when creating a new instance as opposed to retrieving an existing one)
    	 * @param typeCheckOnly whether the instance is obtained for a type check,
    	 * not for actual use
    	 * @return an instance of the bean
    	 * @throws BeansException if the bean could not be created
    	 */
    	@SuppressWarnings("unchecked")
    	protected <T> T doGetBean(
    			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    			throws BeansException {
    
    		String beanName = transformedBeanName(name);
    		Object beanInstance;
    
    		// Eagerly check singleton cache for manually registered singletons.
            // 检查 bean 是否已经被创建
    		Object sharedInstance = getSingleton(beanName);
    		if (sharedInstance != null && args == null) {
    			if (logger.isTraceEnabled()) {
    				if (isSingletonCurrentlyInCreation(beanName)) {
    					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
    							"' that is not fully initialized yet - a consequence of a circular reference");
    				}
    				else {
    					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
    				}
    			}
    			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    		}
    
    		else {
    			// Fail if we're already creating this bean instance:
    			// We're assumably within a circular reference.
    			if (isPrototypeCurrentlyInCreation(beanName)) {
    				throw new BeanCurrentlyInCreationException(beanName);
    			}
    
    			// Check if bean definition exists in this factory.
    			BeanFactory parentBeanFactory = getParentBeanFactory();
    			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    				// Not found -> check parent.
    				String nameToLookup = originalBeanName(name);
    				if (parentBeanFactory instanceof AbstractBeanFactory) {
    					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
    							nameToLookup, requiredType, args, typeCheckOnly);
    				}
    				else if (args != null) {
    					// Delegation to parent with explicit args.
    					return (T) parentBeanFactory.getBean(nameToLookup, args);
    				}
    				else if (requiredType != null) {
    					// No args -> delegate to standard getBean method.
    					return parentBeanFactory.getBean(nameToLookup, requiredType);
    				}
    				else {
    					return (T) parentBeanFactory.getBean(nameToLookup);
    				}
    			}
    
    			if (!typeCheckOnly) {
                    // 标记 bean 已经被创建
    				markBeanAsCreated(beanName);
    			}
    
    			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
    					.tag("beanName", name);
    			try {
    				if (requiredType != null) {
    					beanCreation.tag("beanType", requiredType::toString);
    				}
    				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    				checkMergedBeanDefinition(mbd, beanName, args);
    
    				// Guarantee initialization of beans that the current bean depends on.
                    // 先实例化通过 dependon 依赖的 bean
    				String[] dependsOn = mbd.getDependsOn();
    				if (dependsOn != null) {
    					for (String dep : dependsOn) {
    						if (isDependent(beanName, dep)) {
    							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    						}
    						registerDependentBean(dep, beanName);
    						try {
    							getBean(dep);
    						}
    						catch (NoSuchBeanDefinitionException ex) {
    							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    						}
    					}
    				}
    
    				// Create bean instance.
                    // 创建单例 bean
    				if (mbd.isSingleton()) {
    					sharedInstance = getSingleton(beanName, () -> {
    						try {
    							return createBean(beanName, mbd, args);
    						}
    						catch (BeansException ex) {
    							// Explicitly remove instance from singleton cache: It might have been put there
    							// eagerly by the creation process, to allow for circular reference resolution.
    							// Also remove any beans that received a temporary reference to the bean.
    							destroySingleton(beanName);
    							throw ex;
    						}
    					});
    					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    				}
    
    				else if (mbd.isPrototype()) {
    					// It's a prototype -> create a new instance.
    					Object prototypeInstance = null;
    					try {
    						beforePrototypeCreation(beanName);
    						prototypeInstance = createBean(beanName, mbd, args);
    					}
    					finally {
    						afterPrototypeCreation(beanName);
    					}
    					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    				}
    
    				else {
    					String scopeName = mbd.getScope();
    					if (!StringUtils.hasLength(scopeName)) {
    						throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
    					}
    					Scope scope = this.scopes.get(scopeName);
    					if (scope == null) {
    						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    					}
    					try {
    						Object scopedInstance = scope.get(beanName, () -> {
    							beforePrototypeCreation(beanName);
    							try {
    								return createBean(beanName, mbd, args);
    							}
    							finally {
    								afterPrototypeCreation(beanName);
    							}
    						});
    						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    					}
    					catch (IllegalStateException ex) {
    						throw new ScopeNotActiveException(beanName, scopeName, ex);
    					}
    				}
    			}
    			catch (BeansException ex) {
    				beanCreation.tag("exception", ex.getClass().toString());
    				beanCreation.tag("message", String.valueOf(ex.getMessage()));
    				cleanupAfterBeanCreationFailure(beanName);
    				throw ex;
    			}
    			finally {
    				beanCreation.end();
    			}
    		}
    
    		return adaptBeanInstance(name, beanInstance, requiredType);
    	}
    
    1. DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory singletonFactory)
    /**
    	 * Return the (raw) singleton object registered under the given name,
    	 * creating and registering a new one if none registered yet.
    	 * @param beanName the name of the bean
    	 * @param singletonFactory the ObjectFactory to lazily create the singleton
    	 * with, if necessary
    	 * @return the registered singleton object
    	 */
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                                                              "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                                                              "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                // 标记 bean 为正在被创建
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
    
    1. AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    /**
    	 * Central method of this class: creates a bean instance,
    	 * populates the bean instance, applies post-processors, etc.
    	 * @see #doCreateBean
    	 */
    	@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.
    		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    			mbdToUse = new RootBeanDefinition(mbd);
    			mbdToUse.setBeanClass(resolvedClass);
    		}
    
    		// Prepare method overrides.
    		try {
    			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.
                // InstantiationAwareBeanPostProcessor 实现类可以在 bean 创建前返回 bean 对象,这个对象可以是代理对象,如果存在 InstantiationAwareBeanPostProcessor 实现类创建了该 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 {
    			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    			if (logger.isTraceEnabled()) {
    				logger.trace("Finished creating instance of bean '" + beanName + "'");
    			}
    			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. AbstractAutowireCapableBeanFactory#doCreateBean()
    /**
    	 * Actually create the specified bean. Pre-creation processing has already happened
    	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
    	 * 

    Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { 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 { populateBean(beanName, mbd, instanceWrapper); 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 { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }

    1. AbstractAutowireCapableBeanFactory#createBeanInstance()

    选择合适的构造方法创建对象

    /**
    	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
    	 * factory method, constructor autowiring, or simple instantiation.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @param args explicit arguments to use for constructor or factory method invocation
    	 * @return a BeanWrapper for the new instance
    	 * @see #obtainFromSupplier
    	 * @see #instantiateUsingFactoryMethod
    	 * @see #autowireConstructor
    	 * @see #instantiateBean
    	 */
    	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);
    
    		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());
    		}
    
    		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    		if (instanceSupplier != null) {
    			return obtainFromSupplier(instanceSupplier, beanName);
    		}
    
    		if (mbd.getFactoryMethodName() != null) {
    			return instantiateUsingFactoryMethod(beanName, mbd, args);
    		}
    
    		// Shortcut when re-creating the same bean...
    		boolean resolved = false;
    		boolean autowireNecessary = false;
    		if (args == null) {
    			synchronized (mbd.constructorArgumentLock) {
    				if (mbd.resolvedConstructorOrFactoryMethod != null) {
    					resolved = true;
    					autowireNecessary = mbd.constructorArgumentsResolved;
    				}
    			}
    		}
    		if (resolved) {
    			if (autowireNecessary) {
    				return autowireConstructor(beanName, mbd, null, null);
    			}
    			else {
    				return instantiateBean(beanName, mbd);
    			}
    		}
    
    		// Candidate constructors for autowiring?
    		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    			return autowireConstructor(beanName, mbd, ctors, args);
    		}
    
    		// Preferred constructors for default construction?
    		ctors = mbd.getPreferredConstructors();
    		if (ctors != null) {
    			return autowireConstructor(beanName, mbd, ctors, null);
    		}
    
    		// No special handling: simply use no-arg constructor.
    		return instantiateBean(beanName, mbd);
    	}
    
    1. AbstractAutowireCapableBeanFactory#doCreateBean()

    这时会到第八步的方法,这是虽然已经创建对象成功了,但是还有很多事情要做,详情请看下面。

    1. AbstractAutowireCapableBeanFactory#populateBean()

    为 bean 注入成员变量

    /**
    	 * Populate the bean instance in the given BeanWrapper with the property values
    	 * from the bean definition.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @param bw the BeanWrapper with bean instance
    	 */
    	@SuppressWarnings("deprecation")  // for postProcessPropertyValues
    	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    		if (bw == null) {
    			if (mbd.hasPropertyValues()) {
    				throw new BeanCreationException(
    						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    			}
    			else {
    				// Skip property population phase for null instance.
    				return;
    			}
    		}
    
    		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    		// state of the bean before properties are set. This can be used, for example,
    		// to support styles of field injection.
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    					return;
    				}
    			}
    		}
    
    		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
    		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    			// Add property values based on autowire by name if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    				autowireByName(beanName, mbd, bw, newPvs);
    			}
    			// Add property values based on autowire by type if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    				autowireByType(beanName, mbd, bw, newPvs);
    			}
    			pvs = newPvs;
    		}
    
    		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
    		PropertyDescriptor[] filteredPds = null;
    		if (hasInstAwareBpps) {
    			if (pvs == null) {
    				pvs = mbd.getPropertyValues();
    			}
    			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    				if (pvsToUse == null) {
    					if (filteredPds == null) {
    						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    					}
    					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    					if (pvsToUse == null) {
    						return;
    					}
    				}
    				pvs = pvsToUse;
    			}
    		}
    		if (needsDepCheck) {
    			if (filteredPds == null) {
    				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    			}
    			checkDependencies(beanName, mbd, filteredPds, pvs);
    		}
    
    		if (pvs != null) {
    			applyPropertyValues(beanName, mbd, bw, pvs);
    		}
    	}
    
    1. AbstractAutowireCapableBeanFactory#initializeBean()

    初始化 bean,这个方法会调用 bean 的后置处理器和初始化方法,由此可见,bean 的后置处理器时在 bean 初始化方法执行前后调用的。

    /**
    	 * Initialize the given bean instance, applying factory callbacks
    	 * as well as init methods and bean post processors.
    	 * 

    Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { 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()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

    至此,bean 创建完成,被放到 IOC 容器中等待使用。

  • 相关阅读:
    微信小程序开发SSM投票系统+后台管理系统|前后分离VUE
    Pandas将三个聚合结果的列,如何合并到一张表里?
    国王游戏NOIP
    高级IO详解——五种IO模型
    【故障公告】cc攻击又来了,雪上加霜的三月
    TCGA的拷贝数变异CNV可视化
    thymeleaf-extras-shiro(根据当前用户的权限显示对应的标签) 与 shiro的加盐加密
    Yolov5 batch 推理
    pytest框架格式+setup 函数和 teardown 函数和setup_class 和 teardown_class 函数
    Python-模块系列-zip()函数-range()函数-sum()函数-shuffle() 随机函数
  • 原文地址:https://blog.csdn.net/imonkeyi/article/details/127103994