Spring Boot的主要流程,啓動,獲取Bean,注入Bean,以及SpringMVC中響應的主要流程

@Deprecated 要看getBean的操作的朋友請轉Autowire實現

Spring Boot 啓動

SpringApplication的初始化

在這裏插入圖片描述
在這裏插入圖片描述
這裏先做new SpringApplication(Class<?> ... primarySources) 創建SpringApplication

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader; // 傳進來默認爲null
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // 保存傳進來的類
		this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 決定是什麼類型的Web應用
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 獲取ApplicationContextInitializer的子類
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // 獲取ApplicationListener的子類
		this.mainApplicationClass = deduceMainApplicationClass(); // 找到main方法所在的主類
	}

WebApplicationType.deduceFromClassPath()

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() { // 通過Class.forName來判斷是否存在對應的類,如果不存在將拋出的ClassNotFoundException吸收轉成false。
		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;
	}
	
public static boolean isPresent(String className, @Nullable ClassLoader classLoader) {
		try {
			forName(className, classLoader);
			return true;
		}
		catch (IllegalAccessError err) {
			throw new IllegalStateException("Readability mismatch in inheritance hierarchy of class [" +
					className + "]: " + err.getMessage(), err);
		}
		catch (Throwable ex) {
			// Typically ClassNotFoundException or NoClassDefFoundError...
			return false;
		}
	}

SpringApplication.getSpringFactoriesInstances()

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = getClassLoader();
		// Use names and ensure unique to protect against duplicates
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}

SpringFactoriesLoader.loadFactoryNames()

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		String factoryTypeName = factoryType.getName();
		return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
	}
/**
* 從META-INF/下的spring.factories中獲取對應類,並裝進MutiValueMap
*/
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		try {
			Enumeration<URL> urls = (classLoader != null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

createSpringFactoriesInstances

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
			ClassLoader classLoader, Object[] args, Set<String> names) {
		List<T> instances = new ArrayList<>(names.size());
		for (String name : names) {
			try {
				Class<?> instanceClass = ClassUtils.forName(name, classLoader);
				Assert.isAssignable(type, instanceClass);
				Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
				T instance = (T) BeanUtils.instantiateClass(constructor, args); // 通過反射,獲取類的構造器Constructor,然後Constructor.newInstances()生成對象
				instances.add(instance);
			}
			catch (Throwable ex) {
				throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
			}
		}
		return instances;
	}

spring.factories裏面的東西
以Spring Boot autoConfigure爲例, 上面的getSpringFactoriesInstances就會把SharedMetadataReaderFactoryContextInitializerConditionEvaluationReportLoggingListener這兩個ApplicationContextInitailzer加載到SpringApplication中。
在這裏插入圖片描述
deduceMainApplicationClass

	private Class<?> deduceMainApplicationClass() {
		try {
			StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
			for (StackTraceElement stackTraceElement : stackTrace) { // 找到main方法所在的類,設置爲主類
				if ("main".equals(stackTraceElement.getMethodName())) {
					return Class.forName(stackTraceElement.getClassName());
				}
			}
		}
		catch (ClassNotFoundException ex) {
			// Swallow and continue
		}
		return null;
	}

初始化IOC容器也就是ApplicationContext

public ConfigurableApplicationContext run(String... args) {
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty(); // awt相關,這裏不做解析。
		SpringApplicationRunListeners listeners = getRunListeners(args); // 這裏和 new SpringApplication一樣,內部都是調用getSpringFactoriesInstances,只不過這裏是獲取SpringApplicationRunListener。
		listeners.starting(); // 遍歷所有SpringApplication中的SpringApplicationRunListener,並調用starting()方法。
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 將args包裝起來,下面代碼就不用直接使用args了。
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 獲取當前webApplicationType對應的environment
			configureIgnoreBeanInfo(environment); // 如果配置了`spring.beaninfo.ignore`屬性就設置對應的系統屬性爲true。
			Banner printedBanner = printBanner(environment); // 打印Banner。Banner修改可以放在resources中命名爲banner.txt。
			context = createApplicationContext(); //獲取當前webApplicationType對應的context。
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context); // 這裏和 new SpringApplication一樣,內部都是調用getSpringFactoriesInstances,只不過這裏是獲取SpringBootExceptionReporter。
			prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 完成Context的主要配置,加載BeanDefinition
			refreshContext(context); // 極多操作。 1、加載各種BeanPostProcessor,各種BeanPostProcessor執行postProcessBeanFactory,以MapperScannerConfiguer爲例,它實現了加載classpath下的帶有@Mapper的類。2、創建WebServer。3、初始化單例bean。
			afterRefresh(context, applicationArguments);
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

preparEnvironment

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// Create and configure the environment
		ConfigurableEnvironment environment = getOrCreateEnvironment(); // 如果有就直接返回environment,沒有就根據 new SpringApplication時存放的webApplicationType決定環境。
		configureEnvironment(environment, applicationArguments.getSourceArgs()); // 將environment處理下args
		ConfigurationPropertySources.attach(environment);
		listeners.environmentPrepared(environment); // 每個Listener調用environmentPrepared()
		bindToSpringApplication(environment); // 將環境綁定到SpringApplication上
		if (!this.isCustomEnvironment) {
			environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
					deduceEnvironmentClass());
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}

preparContext

	private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		context.setEnvironment(environment); // 容器設置環境。
		postProcessApplicationContext(context); // 後置處理context,比如設置ResourceLoader。
		applyInitializers(context); // new SpringApplication中加載的SpringApplicationInitializer調用initialize()。
		listeners.contextPrepared(context); // SpringApplicationListener 調用contextPrepared()
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		// Add boot specific singleton beans
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // 獲取BeanFactory
		beanFactory.registerSingleton("springApplicationArguments", applicationArguments); // 註冊applicationArguments 到DefaultSingletonBeanRegistry中,以"springApplicationArguments"爲key
		if (printedBanner != null) {
			beanFactory.registerSingleton("springBootBanner", printedBanner);
		}
		if (beanFactory instanceof DefaultListableBeanFactory) {
			((DefaultListableBeanFactory) beanFactory)
					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.lazyInitialization) {
			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
		}
		// Load the sources
		Set<Object> sources = getAllSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		load(context, sources.toArray(new Object[0])); // 加載各種Bean變成BeanDefinition
		listeners.contextLoaded(context); // SpringApplicationListener調用contextLoaded()
	}

load

protected void load(ApplicationContext context, Object[] sources) {
		if (logger.isDebugEnabled()) {
			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
		}
		BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources); // 創建BeanDefinitionReader和BeanDefinitionScanner。
		if (this.beanNameGenerator != null) {
			loader.setBeanNameGenerator(this.beanNameGenerator);
		}
		if (this.resourceLoader != null) {
			loader.setResourceLoader(this.resourceLoader);
		}
		if (this.environment != null) {
			loader.setEnvironment(this.environment);
		}
		loader.load(); // 調用BeanDefinitionLoader.load()讀取sources,然後調用load()來創建BeanDefinition。我們XML裏或者使用@Component @Contoller @Service @Bean之類修飾的類,將會被創建成BeanDefinition,然後包裝進BeanDefinitionHolder,最終裝到AnnotatedBeanDefinitionRegisty或者XMLBeanDefinitionRegisty中。
	}
protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
		return new BeanDefinitionLoader(registry, sources);
	}
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
		Assert.notNull(registry, "Registry must not be null");
		Assert.notEmpty(sources, "Sources must not be empty");
		this.sources = sources;
		this.annotatedReader = new AnnotatedBeanDefinitionReader(registry); // 基於註解的BeanDefinitionReader。
		this.xmlReader = new XmlBeanDefinitionReader(registry); // 基於XML的BeanDefinitionReader。
		if (isGroovyPresent()) {
			this.groovyReader = new GroovyBeanDefinitionReader(registry);
		}
		this.scanner = new ClassPathBeanDefinitionScanner(registry); // 掃描類路徑下的所有Bean的Scanner。
		this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
	}

獲取Bean

首先說明一點,getBean是BeanFactory定義的方法。

AbstractBeanFactory對於getBean的實現

交給doGetBean去實現

 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return this.doGetBean(name, requiredType, (Object[])null, false);
    }

doGetBean()

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name); // 獲取bean的名稱,因爲這個name有可能是一個Bean的別名,以及是帶有&的FactoryBean。
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName); // 從DefaultSingletonBeanRegistry的singetonObject這個ConcurrentHashMap中獲取這個bean對象。
		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 + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); // 在裏面判斷了是否name以&開頭,如果是則說明是FactoryBean,需要創建FactoryBean的實例化對像,否則直接返回。
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) { // 如果此時有其他線程在創建這個bean就跳過
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory(); // 獲取父容器
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 父容器存在,且不含有這個bean的BeanDefiniton
				// 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) {
				markBeanAsCreated(beanName);
			}
			// 此時自身就是最頂層容器
			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 獲取BeanDefinition
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				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.
				if (mbd.isSingleton()) { // 如果是單例
					sharedInstance = getSingleton(beanName, () -> { // 這裏使用lambda構造了一個ObjectFactory的匿名對象。getSingleton內部就是判斷singletonObjects是否存在這個bean,如果存在就返回,否則調用AbstractAutoWireCapableBeanFactoryd的createBean方法來創建Bean對象.
						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;
						}
					});
					bean = 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);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final 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);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

getObjectFromInstance

	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name)) { // 如果這個類的名稱符合FactoryBean,以&開頭的
			if (beanInstance instanceof NullBean) { // 如果是Null就返回
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) { // 如果這個Bean對象不是FactoryBean,拋出異常
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (!(beanInstance instanceof FactoryBean)) { // 如果他不是一個FactoryBean,就直接返回
			return beanInstance;
		}
		// 說明這個實例,是一個FactoryBean
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			object = getCachedObjectForFactoryBean(beanName); // 由FactoryBean創建的對象應該保存在FactoryBeanRegistrySupport的factoryBeanObjectCache中。於是嘗試從這個map中獲取
		}
		if (object == null) { // cache中不存在,則調用FactoryBean的getObject方法實例化對象
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

instantiateBean

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); // 內部調用Constructor.newInstance來實例化對象
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

initalizeBean

protected Object initializeBean(final String beanName, final 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); // 調用BeanPostProcessor的postProcessBeforeInitialization()
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd); // 調用initMethod指定的初始化方法初始化對象
		}
		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); // 調用BeanPostProcessor的postProcessorAfterBeanInitializtion()
		}

		return wrappedBean;
	}

總的來說,BeanFactory的getBean分爲下面幾點:
1、判斷是否在DefaultSingletonBeanRegistry中。如果存在則判斷是否是一個FactoryBean對象,如果是就調用FactoryBean的getObject獲取對象,不是則直接返回對象。
2、判斷父容器是否存在,並且父容器中是否存在這個Bean的BeanDefinition,如果父容器存在且不存在這個Bean,則遞歸地交給父容器去getBean。如果此時自己就是父容器,那麼
就獲取BeanDefinition,然後獲取這個類的依賴類,然後判斷是否存在循環依賴,如果出現循環依賴則拋出異常。然後註冊依賴類並且getBean去實例化依賴類。
3、如果BeanDefinition中描述這個類是單例的,則通過Lambda表達式匿名的創建一個ObjectFactory。通過DefaultSingletonBeanRegistry的getSingleton來註冊這個匿名類生成的對象。
4、匿名類調用的是AbstrctAutowireCapableBeanFactory的createBean,內部調用doCreateBean來實例化這個類。doCreateBean首先通過反射獲取類的Constructor,然後通過newInstance來創建對象。然後將其包裝成BeanWrapper。然後調用註冊到這個BeanFactory上的BeanPostProcessor的postProcessBeforeInitialization()以及postProcessAfterInitialization()。在前置和後置處理中間,調用的是指定的initMethod對對象進行初始化。
5、最後,根據是否是單例來決定放不放進singletonObject這個Map中。然後返回。

SpringMVC響應流程

DispatcherServlet

請求首先到達doService在完成相關變量的初始化後交給doDispatch

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;

                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest); // 獲取這個請求對應的HandlerExecutionChain
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); // 獲取支持這個HandlerExecutionChain的HandlerAdapter。內部通過遍歷所有HanlderAdapter,並調用supports來選擇。通常是RequestMappingHandlerAdapter。
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }

                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 真正邏輯處理入口,會調用具體的Controller的方法,然後根據返回類型決定返回ModelAndView
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

getHandler

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Iterator var2 = this.handlerMappings.iterator();

        HandlerExecutionChain handler;
        do {
            if (!var2.hasNext()) {
                return null;
            }

            HandlerMapping hm = (HandlerMapping)var2.next();
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
            }

            handler = hm.getHandler(request);
        } while(handler == null);

        return handler;
    }


 public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Object handler = this.getHandlerInternal(request); // 獲取到請求處理的方法
        if (handler == null) {
            handler = this.getDefaultHandler();
        }

        if (handler == null) {
            return null;
        } else {
            if (handler instanceof String) {
                String handlerName = (String)handler;
                handler = this.getApplicationContext().getBean(handlerName); // 如果獲取到的是String,則返回這個Bean作爲HandlerExecutionChain
            }

            HandlerExecutionChain executionChain = this.getHandlerExecutionChain(handler, request); // 將這個方法的攔截器拼裝成HandlerExecutionChain
            if (CorsUtils.isCorsRequest(request)) {
                CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
                CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
                CorsConfiguration config = globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig;
                executionChain = this.getCorsHandlerExecutionChain(request, executionChain, config);
            }

            return executionChain;
        }
    }



protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        String lookupPath = this.getUrlPathHelper().getLookupPathForRequest(request); // 找到這個請求對應的路徑
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Looking up handler method for path " + lookupPath);
        }

        this.mappingRegistry.acquireReadLock();

        HandlerMethod var4;
        try {
            HandlerMethod handlerMethod = this.lookupHandlerMethod(lookupPath, request); // 根據這個路徑找到Controller的具體方法
            if (this.logger.isDebugEnabled()) {
                if (handlerMethod != null) {
                    this.logger.debug("Returning handler method [" + handlerMethod + "]");
                } else {
                    this.logger.debug("Did not find handler method for [" + lookupPath + "]");
                }
            }

            var4 = handlerMethod != null ? handlerMethod.createWithResolvedBean() : null;
        } finally {
            this.mappingRegistry.releaseReadLock();
        }

        return var4;
    }

HandlerAdapter::supports
在這裏插入圖片描述
handle

 public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return this.handleInternal(request, response, (HandlerMethod)handler);
    }


 protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        this.checkRequest(request);
        ModelAndView mav;
        if (this.synchronizeOnSession) { // 如果需要同步會話,就會加鎖
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object mutex = WebUtils.getSessionMutex(session);
                synchronized(mutex) {
                    mav = this.invokeHandlerMethod(request, response, handlerMethod);
                }
            } else {
                mav = this.invokeHandlerMethod(request, response, handlerMethod);
            }
        } else {
            mav = this.invokeHandlerMethod(request, response, handlerMethod); // 注意這裏
        }

        if (!response.containsHeader("Cache-Control")) {
            if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
                this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
            } else {
                this.prepareResponse(response);
            }
        }

        return mav;
    }


protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        ServletWebRequest webRequest = new ServletWebRequest(request, response);

        Object result;
        try { // 前半部分都是創建MVC容器,跳過
            WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
            ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
            ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
            invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
            invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
            invocableMethod.setDataBinderFactory(binderFactory);
            invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
            modelFactory.initModel(webRequest, mavContainer, invocableMethod);
            mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
            AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
            asyncWebRequest.setTimeout(this.asyncRequestTimeout);
            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
            asyncManager.setTaskExecutor(this.taskExecutor);
            asyncManager.setAsyncWebRequest(asyncWebRequest);
            asyncManager.registerCallableInterceptors(this.callableInterceptors);
            asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
            if (asyncManager.hasConcurrentResult()) {
                result = asyncManager.getConcurrentResult();
                mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
                asyncManager.clearConcurrentResult();
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Found concurrent result value [" + result + "]");
                }

                invocableMethod = invocableMethod.wrapConcurrentResult(result); 
            }

            invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]); // 注意這裏
            if (!asyncManager.isConcurrentHandlingStarted()) {
                ModelAndView var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
                return var15;
            }

            result = null;
        } finally {
            webRequest.requestCompleted();
        }

        return (ModelAndView)result;
    }


public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
        Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs); // 獲取Controller中方法的執行結果
        this.setResponseStatus(webRequest);
        if (returnValue == null) {
            if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) {
                mavContainer.setRequestHandled(true);
                return;
            }
        } else if (StringUtils.hasText(this.getResponseStatusReason())) {
            mavContainer.setRequestHandled(true);
            return;
        }

        mavContainer.setRequestHandled(false);

        try {
            this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest); // 這邊就是判斷是否要進行MVC渲染還是直接返回JSON等值的處理。
        } catch (Exception var6) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace(this.getReturnValueHandlingErrorMessage("Error handling return value", returnValue), var6);
            }

            throw var6;
        }
    }

  public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
        Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(this.getMethod(), this.getBeanType()) + "' with arguments " + Arrays.toString(args));
        }

        Object returnValue = this.doInvoke(args); // 調用具體方法
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Method [" + ClassUtils.getQualifiedMethodName(this.getMethod(), this.getBeanType()) + "] returned [" + returnValue + "]");
        }

        return returnValue;
    }




    protected Object doInvoke(Object... args) throws Exception {
        ReflectionUtils.makeAccessible(this.getBridgedMethod());

        try {
            return this.getBridgedMethod().invoke(this.getBean(), args); // 這裏的BridgedMethod已經就是具體的處理方法,這裏調用的就是Controller中的方法了。
        } catch (IllegalArgumentException var5) {
            this.assertTargetBean(this.getBridgedMethod(), this.getBean(), args);
            String text = var5.getMessage() != null ? var5.getMessage() : "Illegal argument";
            throw new IllegalStateException(this.getInvocationErrorMessage(text, args), var5);
        } catch (InvocationTargetException var6) {
            Throwable targetException = var6.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException)targetException;
            } else if (targetException instanceof Error) {
                throw (Error)targetException;
            } else if (targetException instanceof Exception) {
                throw (Exception)targetException;
            } else {
                String text = this.getInvocationErrorMessage("Failed to invoke handler method", args);
                throw new IllegalStateException(text, targetException);
            }
        }
    }

handleReturnValue

   public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType); // 選擇是由什麼結果處理器來處理運算的結果
        if (handler == null) {
            throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
        } else {
            handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
        }
    }

selectHandler


    private HandlerMethodReturnValueHandler selectHandler(Object value, MethodParameter returnType) {
        boolean isAsyncValue = this.isAsyncReturnValue(value, returnType);
        Iterator var4 = this.returnValueHandlers.iterator();

        HandlerMethodReturnValueHandler handler;
        do {
            do {
                if (!var4.hasNext()) {
                    return null;
                }

                handler = (HandlerMethodReturnValueHandler)var4.next();
            } while(isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler));
        } while(!handler.supportsReturnType(returnType)); // 是否支持這個類型,支持就返回這個handler,以RequestResponseBodyMethodProcessor爲例 “return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);”就是當類上有@ResponseBody或者方法上有這個註解時,返回這個結果處理器。

        return handler;
    }

HandlerMethodReturnValueHandler
在這裏插入圖片描述
以RequestResponseBodyMethodProcessor爲例

public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
        mavContainer.setRequestHandled(true); // 告訴容器,不需要返回MV了
        ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
        ServletServerHttpResponse outputMessage = this.createOutputMessage(webRequest);
        this.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage); // 調用MessageConverters來處理結果,比如String類型則使用StringHttpMessageConverter。普通類使用Jackson2HttpMessageConverter進行處理。
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章