区块链技术博客
www.b2bchain.cn

Spring创建Bean的过程Debug

这篇文章主要介绍了Spring创建Bean的过程Debug的讲解,通过具体代码实例进行16214 讲解,并且分析了Spring创建Bean的过程Debug的详细步骤与相关技巧,需要的朋友可以参考下https://www.b2bchain.cn/?p=16214

本文实例讲述了2、树莓派设置连接WiFi,开启VNC等等的讲解。分享给大家供大家参考文章查询地址https://www.b2bchain.cn/7039.html。具体如下:

目录
  • Spring流程Debug
    • 1.1 Spring测试环境搭建
    • 1.2 Debug容器创建过程
    • 1.3 AbstractApplicationContext的refresh()包含的13个方法分析
      • 方法1:prepareRefresh() => 准备工作
      • 方法2:obtainFreshBeanFactory() => 获得一个刷新的bean容器
      • 方法3:prepareBeanFactory(beanFactory) => 准备(初始化)Bean工厂
      • 方法4:postProcessBeanFactory(beanFactory) => 后置增强Bean(扩展实现)
      • 方法5:invokeBeanFactoryPostProcessors(beanFactory) => 执行BFPP
      • 方法6:registerBeanPostProcessors(beanFactory) => 注册BPP
      • 方法7:initMessageSource() => 国际化设置
      • 方法8:initApplicationEventMulticaster() => 初始化应用程序的多波器和广播器
      • 方法9:onRefresh() => 预留给子类做扩展
      • 方法10:registerListeners() => 注册监听器
      • 方法11:finishBeanFactoryInitialization(beanFactory) => 实例化所有单例对象
      • 方法12:finishRefresh() => 完成刷新
      • 方法13:resetCommonCaches() => 缓存重置

Spring流程Debug

1.1 Spring测试环境搭建

Spring模块概览,绿色是模块,Spring中八大模块,黑色表示该模块包含的jar包(组件)。例如我们想要用IOC容器,也就是绿色的CoreContainer,我们需要导入Beans,Core,Context,SpEL(spring-expression)四个包。

Spring创建Bean的过程Debug
  • Test:测试相关
  • Core Container:IOC容器
  • AOP:面向切面编程
  • Aspects:切面
  • Instrumenttation:跟JDK关联,一般不用
  • Messaging:消息服务,一般不用
  • Data Access/Integration:数据访问与集成(JDBC访问,Transaction事务,ORM对象关系映射,OXM和XML映射一般不用,JMS为Java消息服务Java-message-service一般不用)
  • Web:Web服务(WebSocket网络通信协议,Servlet, Web,Portlet一般不用)

最偷懒的方式,是直接导入Spring-Framework。但是可能导入不必要的包,导致项目打包后比较大

由于Spring-Content中的ApplicationContent是整个IOC的入口。我们导入Spring-context包即可

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-context</artifactId>     <version>5.2.3.RELEASE</version> </dependency>

我们导入spring-content后,默认会导入该组件的依赖jar,spring-content底层的依赖可以看到,实际上我们是导入了Core Container模块:

<dependencies>     <dependency>       <groupId>org.springframework</groupId>       <artifactId>spring-aop</artifactId>       <version>5.2.3.RELEASE</version>       <scope>compile</scope>     </dependency>     <dependency>       <groupId>org.springframework</groupId>       <artifactId>spring-beans</artifactId>       <version>5.2.3.RELEASE</version>       <scope>compile</scope>     </dependency>     <dependency>       <groupId>org.springframework</groupId>       <artifactId>spring-core</artifactId>       <version>5.2.3.RELEASE</version>       <scope>compile</scope>     </dependency>     <dependency>       <groupId>org.springframework</groupId>       <artifactId>spring-expression</artifactId>       <version>5.2.3.RELEASE</version>       <scope>compile</scope>     </dependency>   </dependencies>

新建Spring配置文件spring.xml:

<?xml version="1.0" encoding="UTF-8"?> <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">      <!--注册一个对象,spring回自动创建这个对象-->     <!--     一个bean标签就表示一个对象     id:这个对象的唯一标识     class:注册对象的完全限定名     -->     <bean id="hello" class="com.xiaodai.service.Hello">         <!--使用property标签给对象的属性赋值         name:表示属性的名称         value:表示属性的值         -->         <property name="id" value="1"></property>         <property name="name" value="zhangsan"></property>         <property name="age" value="18"></property>     </bean> </beans>

编写测试类:

import com.xiaodai.service.Hello; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class Test {      public static void main(String[] args) {         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");         Hello hello = applicationContext.getBean("hello", Hello.class);         System.out.println(hello.getName());      }  }

1.2 Debug容器创建过程

从测试类的new ClassPathXmlApplicationContext("spring.xml")开始debug,进入ClassPathXmlApplicationContext,可以看到:

public ClassPathXmlApplicationContext( 			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) 			throws BeansException {  		super(parent); 		// 设置配置文件路径 		setConfigLocations(configLocations); 		if (refresh) { 		        // 核心步骤 			refresh(); 		} 	}

加载配置文件后,进入refresh()方法,该方法是容器初始化的核心步骤。该方法包含十三个方法:

@Override 	public void refresh() throws BeansException, IllegalStateException { 		synchronized (this.startupShutdownMonitor) { 			// Prepare this context for refreshing. 			/**  			 * 准备刷新,做一些最基本的准备化工作 			**/ 			prepareRefresh();  			// Tell the subclass to refresh the internal bean factory. 			/**  			 * 获得一个刷新的bean容器,实质就是获取工厂。 			 * 加载xml等配置文件,用该文件产生的BeanDefinition来创建一个工厂 			**/ 			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  			// Prepare the bean factory for use in this context. 			/** 			 * 准备bean工厂 			**/ 			prepareBeanFactory(beanFactory);  			try { 				// Allows post-processing of the bean factory in context subclasses. 				// 后置增强,方便扩展 				postProcessBeanFactory(beanFactory);  				// Invoke factory processors registered as beans in the context. 				// 实例化并且执行BeanFactoryPostProcessors 				invokeBeanFactoryPostProcessors(beanFactory);  				// Register bean processors that intercept bean creation. 				// 实例化并且注册所有的BeanPostProcessor 				registerBeanPostProcessors(beanFactory);  				// 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. 				// 工作中常用,面试常问。实例化所有非懒加载的实例对象 				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(); 			} 		} 	}

1.3 AbstractApplicationContext的refresh()包含的13个方法分析

结合概览图一个一个方法分析:

Spring创建Bean的过程Debug

方法1:prepareRefresh() => 准备工作

准备刷新,做一些最基本的准备化工作

protected void prepareRefresh() { 		// Switch to active. 		// 设置开始时间 		this.startupDate = System.currentTimeMillis(); 		// 关闭状态设置为false 		this.closed.set(false); 		// 活跃状态设置为true 		this.active.set(true);          // 打印日志 		if (logger.isDebugEnabled()) { 			if (logger.isTraceEnabled()) { 				logger.trace("Refreshing " + this); 			} 			else { 				logger.debug("Refreshing " + getDisplayName()); 			} 		}  		// Initialize any placeholder property sources in the context environment. 		// 初始化属性资源 		initPropertySources();  		// Validate that all properties marked as required are resolvable: 		// see ConfigurablePropertyResolver#setRequiredProperties 		// 获取环境信息,验证属性信息 		getEnvironment().validateRequiredProperties();  		// Store pre-refresh 		// 存储预刷新的一些应用信息的监听器 		ApplicationListeners... 		if (this.earlyApplicationListeners == null) { 			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); 		} 		else { 			// Reset local application listeners to pre-refresh state. 			this.applicationListeners.clear(); 			this.applicationListeners.addAll(this.earlyApplicationListeners); 		}  		// Allow for the collection of early ApplicationEvents, 		// to be published once the multicaster is available... 		// 创建一些监听器事件的集合 		this.earlyApplicationEvents = new LinkedHashSet<>(); 	}

总结:1.设置启动事件 2.设置关闭活跃的状态 3.获取环境对象并设置属性值 4.设置监听器以及需要发布事件的集合

重要的点:

  • 获取环境信息,验证属性信息,getEnvironment().validateRequiredProperties();
  • 存储预刷新的一些应用信息的监听器,在Spring中是空实现,但是SpringBoot中,是有具体的值的

方法2:obtainFreshBeanFactory() => 获得一个刷新的bean容器

获得一个刷新的bean容器,实质就是获取工厂。创建容器对象DefaultListableBeanFactory;加载xml配置文件的属性到当前的工厂中,最重要的就是BeanDefinition

Spring创建Bean的过程Debug

AbstractRefreshableApplicationContext:

// 只要进到这个方法,那么我们创建的一定是一个新的工厂 	@Override 	protected final void refreshBeanFactory() throws BeansException { 		if (hasBeanFactory()) { 		    // 如果存在先销毁,后关闭 			destroyBeans(); 			closeBeanFactory(); 		} 		try { 		    // 创建bean工厂,这里使用的就是DefaultListableBeanFactory。此时创建的工厂里面的属性值都是默认值 			DefaultListableBeanFactory beanFactory = createBeanFactory(); 			// 序列化id 			beanFactory.setSerializationId(getId()); 			// 设置一些属性值 			customizeBeanFactory(beanFactory); 			// 加载bean的定义属性值。该方法有很多重载,非常复杂,核心是do操作 			// 完成配置文件或者配置类文件的加载 			loadBeanDefinitions(beanFactory); 			synchronized (this.beanFactoryMonitor) { 				this.beanFactory = beanFactory; 			} 		} 		catch (IOException ex) { 			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); 		} 	}

方法3:prepareBeanFactory(beanFactory) => 准备(初始化)Bean工厂

为方法2拿到的工厂,设置某些具体的值

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 		// Tell the internal bean factory to use the context's class loader etc. 		// 为bean工厂设置类加载器 		beanFactory.setBeanClassLoader(getClassLoader()); 		// 设置SPEL解析器 		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); 		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));  		// Configure the bean factory with context callbacks. 		// 添加一个BeanPostProcessor 		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 		// 忽略对应接口的实现 		beanFactory.ignoreDependencyInterface(EnvironmentAware.class); 		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); 		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); 		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); 		beanFactory.ignoreDependencyInterface(MessageSourceAware.class); 		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);  		// BeanFactory interface not registered as resolvable type in a plain factory. 		// MessageSource registered (and found for autowiring) as a bean.         // 注册一些依赖 		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); 		beanFactory.registerResolvableDependency(ResourceLoader.class, this); 		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); 		beanFactory.registerResolvableDependency(ApplicationContext.class, this);  		// Register early post-processor for detecting inner beans as 		// ApplicationListeners添加一个BeanPostProcessor增强器 		ApplicationListeners. 		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));  		// Detect a LoadTimeWeaver and prepare for weaving, if found. 		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 			// Set a temporary ClassLoader for type matching. 			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 		}  		// Register default environment beans. 		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); 		} 		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); 		} 		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); 		} 	}

方法4:postProcessBeanFactory(beanFactory) => 后置增强Bean(扩展实现)

空方法,方便扩展

方法5:invokeBeanFactoryPostProcessors(beanFactory) => 执行BFPP

实例化并且执行BeanFactoryPostProcessors

/** 	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans, 	 * respecting explicit order if given. 	 * <p>Must be called before singleton instantiation. 	 * 单例对象之前一定调用,因为单例bean创建后就只有一份 	 */ 	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { 		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());  		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime 		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) 		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 		} 	}

方法6:registerBeanPostProcessors(beanFactory) => 注册BPP

实例化并且注册所有的BeanPostProcessor。实例化Bean之前的准备工作

/** 	 * Instantiate and register all BeanPostProcessor beans, 	 * respecting explicit order if given. 	 * <p>Must be called before any instantiation of application beans. 	 */ 	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { 		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); 	}

方法7:initMessageSource() => 国际化设置

方法8:initApplicationEventMulticaster() => 初始化应用程序的多波器和广播器

也属于准备工作

方法9:onRefresh() => 预留给子类做扩展

空方法

方法10:registerListeners() => 注册监听器

也属于准备工作

/** 	 * Add beans that implement ApplicationListener as listeners. 	 * Doesn't affect other listeners, which can be added without being beans. 	 */ 	protected void registerListeners() { 		// Register statically specified listeners first. 		for (ApplicationListener<?> listener : getApplicationListeners()) { 			getApplicationEventMulticaster().addApplicationListener(listener); 		}  		// Do not initialize FactoryBeans here: We need to leave all regular beans 		// uninitialized to let post-processors apply to them! 		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); 		for (String listenerBeanName : listenerBeanNames) { 			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); 		}  		// Publish early application events now that we finally have a multicaster... 		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; 		this.earlyApplicationEvents = null; 		if (earlyEventsToProcess != null) { 			for (ApplicationEvent earlyEvent : earlyEventsToProcess) { 				getApplicationEventMulticaster().multicastEvent(earlyEvent); 			} 		} 	}

方法11:finishBeanFactoryInitialization(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. 		/** 		 * 把类型转化操作,设置到当前的beanFactory里面去 		**/ 		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 bean post-processor 		// (such as a PropertyPlaceholderConfigurer bean) registered any before: 		// at this point, primarily for resolution in annotation attribute values. 		/** 		 * 判断当前的beanFactory有没有内置的值处理器 		**/ 		if (!beanFactory.hasEmbeddedValueResolver()) { 			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); 		}  		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 		/** 		 * 织入Aware 		**/ 		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. 		/** 		 * 冻结:某些bean不需要进行修改操作了,放入 		**/ 		beanFactory.freezeConfiguration();  		// Instantiate all remaining (non-lazy-init) singletons. 		/** 		 * 实例化所有非懒加载的实例对象(重要) 		**/ 		beanFactory.preInstantiateSingletons(); 	}

实例化所有非懒加载的实例对象方法:

@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. 		/** 		 * 拿到所有注册bean的名称 		 **/ 		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);  		// Trigger initialization of all non-lazy singleton beans... 		// 循环去创建我们需要的单例对象 		for (String beanName : beanNames) { 		    // 拿到bean的定义信息,就是我们在xml配置文件里面指定的一些属性 			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 			// 是否是抽象的,是否是单例的,是否是懒加载的 			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 			    // 判断当前类是否实现了factoryBean接口。一般没实现,直接进入下面的getBean 				if (isFactoryBean(beanName)) { 					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 					if (bean instanceof FactoryBean) { 						final 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 { 				    // 通过beanName。拿到bean 					getBean(beanName); 				} 			} 		}  		// Trigger post-initialization callback for all applicable beans... 		for (String beanName : beanNames) { 			Object singletonInstance = getSingleton(beanName); 			if (singletonInstance instanceof SmartInitializingSingleton) { 				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 				if (System.getSecurityManager() != null) { 					AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 						smartSingleton.afterSingletonsInstantiated(); 						return null; 					}, getAccessControlContext()); 				} 				else { 					smartSingleton.afterSingletonsInstantiated(); 				} 			} 		} 	}

重要方法:

  • getMergedLocalBeanDefinition
/** 	 * Return a merged RootBeanDefinition, traversing the parent bean definition 	 * if the specified bean corresponds to a child bean definition. 	 * @param beanName the name of the bean to retrieve the merged definition for 	 * @return a (potentially merged) RootBeanDefinition for the given bean 	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 	 * @throws BeanDefinitionStoreException in case of an invalid bean definition 	 */ 	 // 返回一个合并好的RootBeanDefinition。整合子类和父类 	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { 		// Quick check on the concurrent map first, with minimal locking. 		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 		if (mbd != null && !mbd.stale) { 			return mbd; 		} 		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 	}
  • getBean() => doGetBean()
/** 	 * 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(final String name, @Nullable final Class<T> requiredType, 			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {          // 获取beanName 		final String beanName = transformedBeanName(name); 		Object bean;  		// 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 + "'"); 				} 			} 			bean = 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); 				} 			}              // 标志位。如果不是类型检查,表示要创建bean,此处在集合中做一个记录 			if (!typeCheckOnly) { 				markBeanAsCreated(beanName); 			}  			try { 			    // 获取beanDefinition 				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 				// 检测beanDefinition 				checkMergedBeanDefinition(mbd, beanName, args);  				// Guarantee initialization of beans that the current bean depends on. 				// 检查当前的bean是否有其他依赖的bean 				String[] dependsOn = mbd.getDependsOn(); 				if (dependsOn != null) { 				    // 如果有依赖的bean,我们要先递归解决其他依赖的bean 					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, () -> { 						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; 	}
  • getSingleton
/** 	 * 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 + "'"); 				} 				beforeSingletonCreation(beanName); 				boolean newSingleton = false; 				boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 				if (recordSuppressedExceptions) { 					this.suppressedExceptions = new LinkedHashSet<>(); 				} 				try { 				    // 实际上就是调用了CreateBean 					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; 		} 	}
  • doCreateBean => 通过上方法的singletonObject = singletonFactory.getObject();进入的
/** 	 * Actually create the specified bean. Pre-creation processing has already happened 	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. 	 * <p>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(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) 			throws BeanCreationException {  		// Instantiate the bean. 		BeanWrapper instanceWrapper = null; 		if (mbd.isSingleton()) { 			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 		} 		if (instanceWrapper == null) { 		    /** 		     * 核心的创建实例化Bean的过程 		    **/ 			instanceWrapper = createBeanInstance(beanName, mbd, args); 		} 		final 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 { 		    /** 		     * 填充属性,上文的实例化只是默认属性值。填充属性是初始化的第一步,第二步是执行init方法 		    **/ 			populateBean(beanName, mbd, instanceWrapper); 			/** 			 * 执行init方法 			**/ 			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 " + 								"'getBeanNamesOfType' 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; 	}

面试题:为甚么循环依赖的解决要使用三级缓存?

  • createBeanInstance => 核心的创建和实例化bean的过程,由doCreateBean调用

大量的反射出现在该方法中,用来创建对象

/** 	 * 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); 	}
  • instantiateBean(beanName, mbd) => 默认无参构造
/** 	 * Instantiate the given bean using its default constructor. 	 * @param beanName the name of the bean 	 * @param mbd the bean definition for the bean 	 * @return a BeanWrapper for the new instance 	 */ 	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); 			} 			BeanWrapper bw = new BeanWrapperImpl(beanInstance); 			initBeanWrapper(bw); 			return bw; 		} 		catch (Throwable ex) { 			throw new BeanCreationException( 					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); 		} 	}
  • instantiate
@Override 	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { 		// Don't override the class with CGLIB if no overrides. 		if (!bd.hasMethodOverrides()) { 			Constructor<?> constructorToUse; 			synchronized (bd.constructorArgumentLock) { 				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; 				if (constructorToUse == null) { 					final Class<?> clazz = bd.getBeanClass(); 					if (clazz.isInterface()) { 						throw new BeanInstantiationException(clazz, "Specified class is an interface"); 					} 					try { 						if (System.getSecurityManager() != null) { 							constructorToUse = AccessController.doPrivileged( 									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); 						} 						else { 							constructorToUse = clazz.getDeclaredConstructor(); 						} 						bd.resolvedConstructorOrFactoryMethod = constructorToUse; 					} 					catch (Throwable ex) { 						throw new BeanInstantiationException(clazz, "No default constructor found", ex); 					} 				} 			} 			return BeanUtils.instantiateClass(constructorToUse); 		} 		else { 			// Must generate CGLIB subclass. 			return instantiateWithMethodInjection(bd, beanName, owner); 		} 	}
  • BeanUtils.instantiateClass => 通过构造器反射创建bean
/** 	 * Convenience method to instantiate a class using the given constructor. 	 * <p>Note that this method tries to set the constructor accessible if given a 	 * non-accessible (that is, non-public) constructor, and supports Kotlin classes 	 * with optional parameters and default values. 	 * @param ctor the constructor to instantiate 	 * @param args the constructor arguments to apply (use {@code null} for an unspecified 	 * parameter, Kotlin optional parameters and Java primitive types are supported) 	 * @return the new instance 	 * @throws BeanInstantiationException if the bean cannot be instantiated 	 * @see Constructor#newInstance 	 */ 	public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { 		Assert.notNull(ctor, "Constructor must not be null"); 		try { 			ReflectionUtils.makeAccessible(ctor); 			if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) { 				return KotlinDelegate.instantiateClass(ctor, args); 			} 			else { 				Class<?>[] parameterTypes = ctor.getParameterTypes(); 				Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters"); 				Object[] argsWithDefaultValues = new Object[args.length]; 				for (int i = 0 ; i < args.length; i++) { 					if (args[i] == null) { 						Class<?> parameterType = parameterTypes[i]; 						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null); 					} 					else { 						argsWithDefaultValues[i] = args[i]; 					} 				} 				return ctor.newInstance(argsWithDefaultValues); 			} 		} 		catch (InstantiationException ex) { 			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); 		} 		catch (IllegalAccessException ex) { 			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); 		} 		catch (IllegalArgumentException ex) { 			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); 		} 		catch (InvocationTargetException ex) { 			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); 		} 	}

方法12:finishRefresh() => 完成刷新

/** 	 * Finish the refresh of this context, invoking the LifecycleProcessor's 	 * onRefresh() method and publishing the 	 * {@link org.springframework.context.event.ContextRefreshedEvent}. 	 */ 	protected void finishRefresh() { 		// Clear context-level resource caches (such as ASM metadata from scanning). 		//  		clearResourceCaches();  		// Initialize lifecycle processor for this context. 		initLifecycleProcessor();  		// Propagate refresh to lifecycle processor first. 		getLifecycleProcessor().onRefresh();  		// Publish the final event. 		publishEvent(new ContextRefreshedEvent(this));  		// Participate in LiveBeansView MBean, if active. 		LiveBeansView.registerApplicationContext(this); 	}

方法13:resetCommonCaches() => 缓存重置

/** 	 * Reset Spring's common reflection metadata caches, in particular the 	 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType} 	 * and {@link CachedIntrospectionResults} caches. 	 * @since 4.2 	 * @see ReflectionUtils#clearCache() 	 * @see AnnotationUtils#clearCache() 	 * @see ResolvableType#clearCache() 	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader) 	 */ 	protected void resetCommonCaches() { 		ReflectionUtils.clearCache(); 		AnnotationUtils.clearCache(); 		ResolvableType.clearCache(); 		CachedIntrospectionResults.clearClassLoader(getClassLoader()); 	}

最后回顾整个流程概览图:

Spring创建Bean的过程Debug

本文转自互联网,侵权联系删除Spring创建Bean的过程Debug

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » Spring创建Bean的过程Debug
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们