Spring技术内幕2Spring Framework的核心:IoC容器的实现

Spring Framework 深度解析:架构与核心思想 Spring Framework 是一个轻量级、一站式的企业级 Java 开发框架,旨在简化 J2EE 开发。其基础版本大小仅约 2MB,却提供了从 IoC 容器到 Web MVC 的全面支持。选择自由:提供多种实现方式,让开发者灵活选择。兼容性强:保持后向兼容,支持多种技术集成。高质量代码:注重 API 设计和代码严谨性。Spring 的目标是通过基于 POJO(Plain Old Java Object)的编程模型,提升开发效率并促进最佳实践,使开发者专注于业务逻辑而非底层复杂性。 阅读详情

1SpringIoC容器概述

IoC容器和依赖反转模式:
早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。许多非凡的应用(比HelloWorld.java更加优美,更加复杂)都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要,与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么如你所见,这将导致代码高度耦合并且难以测试。


Spring IoC的应用场景:
在Spring中,Spring IoC提供了一个基本的JavaBean容器,通过IoC模式管理依赖关系,并通过依赖注入和AOP切面编程增强了为JavaBean这样的POJO对象赋予事务管理、生命周期管理等基本功能;
而对于EJB,一个简单的EJB组件需要编写远程/本地接口、Home接口以及Bean的实现类,而EJB运行是不能脱离EJB容器的,查找其他的EJB组件也需要诸如JNDI这样的方式,从而造成了对EJB容器和技术规范的 依赖。


2IoC容器系列的设计和实现:BeanFactory和ApplicationContext

两个主要的容器系列:
BeanFactory接口的实现,这个系列仅实现了容器的基本功能;The root interface for accessing a Spring bean container. This is the basic client view of a bean container;
ApplicationContext应用上下文,他作为容器的高级形态而存在。(此接口父接口HierarchicalBeanFactory也继承自BeanFactory)Central interface to provide configuration for an application. This is read-only while the application is running, but may be reloaded if the implementation supports this. 


Spring的IoC容器系列:把IoC容器比喻成水桶,水桶有大小,作用也不同。
BeanDefinition:来管理基于Spring的应用中的各种对象以及他们之间的相互依赖关系,抽象了我们对Bean的定义,是容器起作用的主要数据类型。A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations. 


Spring IoC容器设计:
如图:Spring IoC容器接口设计图.jpg


·从接口BeanFactory到HierarchicalBeanFactory,再到ConfigurableBeanFactory,是一条主要的BeanFactory设计路线。
BeanFactory接口定义了基本的IoC容器的规范。基本定义了获取bean和获取判断bean全局范围类型等。
HierarchicalBeanFactory,提供了getParentBeanFactory,使BeanFactory具备了双亲IoCring容器管理能力,和containsLocalBean(String name)两个方法。
ConfigurableBeanFactory,主要定义了一些对BeanFactory的配置功能。


·第两条接口设计主线是,以ApplicationContext应用上下文接口为核心的接口设计,从BeanFactory到ListableBeanFactory,再到ApplicationContext,再到ConfigurableApplicationContext或WebApplicationContext。
在这个接口体系中,ListableBeanFactory和HierarchicalBeanFactory两个接口,连接BeanFactory接口定义和ApplicationContext应用上下文的接口定义。
在ListableBeanFactory接口中,细化了许多BeanFactory接口功能。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver

·设计的主要接口关系,具体的IoC容器都是在这个接口体系下实现的,比如DefaultListableBeanFactory。


1、BeanFactory的应用场景
用户使用容器时,可以使用转义符"&"来得到FactoryBean本身。有了BeanFactory得到定义,可以进行一些额外的操作。
核心的getBean方法,又提供了一些对bean的判断等,bean数据都在BeanDefinition中定义。


2、BeanFactory容器的设计原理
我们可以从继承体系的发展上看到IoC容器各项功能的实现过程。
例子:XmlBeanFactory简历在DefaultListableBeanFactory基础上(ApplicationContext中也用到了他)。XmlBeanFactory利用XmlBeanDefinitionReader,通过方法loadBeanDefinitions(resource)读取以XML方法定义的BeanDefinition的IoC容器。通过Spring中的Resource I/O操作类,来获取XML形式定义的BeanDefinition。

3、ApplicationContext的应用场景
支持不同的信息源;访问资源;支持应用事件;在ApplicationContext中提供的附加服务。


4、ApplicationContext容器的设计原理
FileSystemXmlApplicationContext:
应用上下文的主要功能已经在基类AbstractXmlApplicationContext中实现了。
他本身只需要实现两个功能:在构造器中refresh();怎么从文件系统中加载XML的Bean定义资源。



3IoC容器的初始化过程

IoC容器的初始化是由refresh()方法来启动的。这个启动包括BeanDefinition的Resource定位、载入和注册三个基本过程。
Spring把这三个过程分开,并使用不同的模式来完成,可以灵活对这三个过程进行剪裁和扩展。


Resource定位:BeanDefinition的资源定位,由ResourceLoader通过统一的Resource接口来完成。
BeanDefinition载入:把用户定义好的Bean表示成IoC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。
IoC容器注册这些BeanDefinition过程:通过调用BeanDefinitionRegistry接口的实现来完成。注册到一个HashMap中去。


这三个步骤不包含Bean依赖注入的实现。
Bean定义的载入和依赖注入是两个独立的过程。
依赖注入一般发生在第一次通过getBean向容器索取Bean的时候。(当设置lazyinit属性,这个Bean的依赖注入在IoC容器初始化时就预先完成。)


核心类:
org.springframework.context.support.AbstractApplicationContext:refresh()
Abstract implementation of the org.springframework.context.ApplicationContext interface. Doesn't mandate the type of storage used for configuration; simply implements common context functionality. Uses the Template Method design pattern, requiring concrete subclasses to implement abstract methods. 


org.springframework.context.support.AbstractRefreshableApplicationContext:createBeanFactory()
Base class for org.springframework.context.ApplicationContext implementations which are supposed to support multiple calls to refresh(), creating a new internal bean factory instance every time. Typically (but not necessarily), such a context will be driven by a set of config locations to load bean definitions from. 


org.springframework.beans.factory.support.DefaultListableBeanFactory:
Default implementation of the org.springframework.beans.factory.ListableBeanFactory and BeanDefinitionRegistry interfaces: a full-fledged bean factory based on bean definition objects. 
Typical usage is registering all bean definitions first (possibly read from a bean definition file), before accessing beans. Bean definition lookup is therefore an inexpensive operation in a local bean definition table, operating on pre-built bean definition metadata objects. 
Can be used as a standalone bean factory, or as a superclass for custom bean factories. Note that readers for specific bean definition formats are typically implemented separately rather than as bean factory subclasses: see for example PropertiesBeanDefinitionReader and org.springframework.beans.factory.xml.XmlBeanDefinitionReader. 


org.springframework.beans.factory.xml.XmlBeanDefinitionReader:loadBeanDefinitions()
Bean definition reader for XML bean definitions. Delegates the actual XML document reading to an implementation of the BeanDefinitionDocumentReader interface. 
Typically applied to a org.springframework.beans.factory.support.DefaultListableBeanFactory or a org.springframework.context.support.GenericApplicationContext. 
This class loads a DOM document and applies the BeanDefinitionDocumentReader to it. The document reader will register each bean definition with the given bean factory, talking to the latter's implementation of the org.springframework.beans.factory.support.BeanDefinitionRegistry interface.


org.springframework.beans.factory.xml.BeanDefinitionParserDelegate:parseBeanDefinitionElement()
Stateful delegate class used to parse XML bean definitions. Intended for use by both the main parser and any extension BeanDefinitionParsers or BeanDefinitionDecorators.














1BeanDefinition的Resource定位:
使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefinition。这时使用的是ClassPathResource。
基类DefaultResourceLoader提供了ResourceLoader读入以Resource定义的BeanDefinition的能力。这样就可以使DefaultListableBeanFactory从bean的定义资源方式中全身而退,做一个纯碎的IoC容器。
FileSystemXmlApplicationContext通过继承AbstractApplicationContext具备了ResourceLoader读入以及Resource定义的BeanDefinition能力,因为AbstractApplicationContext的基类是DefaultResourceLoader。
refresh()内部一处调用到了AbstractRefreshableApplicationContext的refreshBeanFactory(),这个方法通过createBeanFactory()构建了一个IoC容器供ApplicationContext使用。这个IoC容器就是上面的DefaultListableBeanFactory,同时,他启动了loadBeanDefinitions(beanFactory)来载入BeanDefinition。具体的资源载入在XmlBeanDefinitionReader读入BeanDefinition时完成。

AbstractRefreshableApplicationContext:
	/**
	 * This implementation performs an actual refresh of this context's underlying
	 * bean factory, shutting down the previous bean factory (if any) and
	 * initializing a fresh bean factory for the next phase of the context's lifecycle.
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		//这里判断,如果已经建立BeanFactory,则销毁并关闭该BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		//这里是创建并设置持有的DefaultListableBeanFactory的地方同时调用loadBeanDefinitions(beanFactory)再载入BeanDefinition的信息。
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
	
	
	/**
	 * Create an internal bean factory for this context.
	 * Called for each {@link #refresh()} attempt.
	 * <p>The default implementation creates a
	 * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
	 * with the {@linkplain #getInternalParentBeanFactory() internal bean factory} of this
	 * context's parent as parent bean factory. Can be overridden in subclasses,
	 * for example to customize DefaultListableBeanFactory's settings.
	 * @return the bean factory for this context
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
	 */
	 //这就是在上下文中创建DefaultListableBeanFactory的地方,而getInternalParentBeanFactory()会根据容器已有的双亲IoC容器的信息来生成DefaultListableBeanFactory的双亲IoC容器。
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}	

	/**
	 * Load bean definitions into the given bean factory, typically through
	 * delegating to one or more bean definition readers.
	 * @param beanFactory the bean factory to load bean definitions into
	 * @throws BeansException if parsing of the bean definitions failed
	 * @throws IOException if loading of bean definition files failed
	 * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 */
	 //这里是使用BeanDefinitionReader载入Bean定义的地方,因为允许有多种载入方式,虽然用的最多的是XML定义的形式,这里同一个一个抽象函数把具体的实现委托给子类来完成。
	protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
			throws BeansException, IOException;	
	父类loadBeanDefinitions实现:		
	AbstractXmlApplicationContext:loadBeanDefinitions(DefaultListableBeanFactory beanFactory)	
	/**
	 * Loads the bean definitions via an XmlBeanDefinitionReader.
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}		
	
	//DefaultResourceLoader对于取得Resource的具体过程
	public Resource getResource(String location) {
		Assert.notNull(location, "Location must not be null");
		if (location.startsWith(CLASSPATH_URL_PREFIX)) {
			return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
		}
		else {
			try {
				// Try to parse the location as a URL...
				URL url = new URL(location);
				return new UrlResource(url);
			}
			catch (MalformedURLException ex) {
				// No URL -> resolve as resource path.
				return getResourceByPath(location);
			}
		}
	}	

2BeanDefinition的载入和解析:
IoC容器对Bean的管理和 依赖注入功能的实现,是通过其持有的BeanDefinition进行各种相关操作完成的。
IoC容器的refresh过程

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//这里是在子类中启动refreshBeanFactory()的地方
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//设置BeanFactory的后置处理
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册Bean的后处理器,在bean的创建过程中被调用
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//对上下文中的消息源进行初始化
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化上下文中的事件机制
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//初始化其他的特殊bean
				onRefresh();

				// Check for listener beans and register them.
				//检查监听bean并且将这些bean向容器注册
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//实例化所有的(non-lazy-init)单例
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//发布容器事件,结束Refresh过程
				finishRefresh();
			}

			catch (BeansException ex) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
		}
	}


	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建IoC容器,这使用的是DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			//启动对BeanDefinition的载入
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

如图:BeanDefinition载入中的交互过程.jpg


具体的载入实现没在AbstractRefreshApplicationContext中实现在
	AbstractXmlApplicationContext:loadBeanDefinitions(DefaultListableBeanFactory beanFactory)	
	/**
	 * Loads the bean definitions via an XmlBeanDefinitionReader.
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	@Override
	//这里是实现loadBeanDefinitions的地方
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//创建XmlBeanDefinitionReader,并通过回调设置到BeanFactory中去
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		//设置父类DefaultResourceLoader
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		//启动bean定义信息载入过程
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}		
	
	
	/**
	 * Load the bean definitions with the given XmlBeanDefinitionReader.
	 * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
	 * method; hence this method is just supposed to load and/or register bean definitions.
	 * @param reader the XmlBeanDefinitionReader to use
	 * @throws BeansException in case of bean registration errors
	 * @throws IOException if the required XML document isn't found
	 * @see #refreshBeanFactory
	 * @see #getConfigLocations
	 * @see #getResources
	 * @see #getResourcePatternResolver
	 */
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		//以Resource的方式获得配置文件的资源位置
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			//开始进行BeanDefinition的载入
			reader.loadBeanDefinitions(configResources);
		}
		//以String的形式获得配置文件的位置
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}	
	
	而这时XmlBeanDefinitionReader的父类AbstractBeanDefinitionReader已经为BeanDefinition的载入做好了准备。
	public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		//如果Resource为空,则停止BeanDefinition的载入
		Assert.notNull(resources, "Resource array must not be null");
		int counter = 0;
		//启动BeanDefinition的载入过程,会便利Resource集合所有包含BeanDefinition信息
		for (Resource resource : resources) {
			counter += loadBeanDefinitions(resource);
		}
		return counter;
	}	
	
	/**
	 * Load bean definitions from the specified XML file.
	 * @param encodedResource the resource descriptor for the XML file,
	 * allowing to specify an encoding to use for parsing the file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	//载入XML形式的BeanDefinition的地方
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isInfoEnabled()) {
			logger.info("Loading XML bean definitions from " + encodedResource.getResource());
		}

		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<EncodedResource>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		//这里得到XML文件,并得到IO的InputResource准备进行读取
		try {
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}
	
	
	/**
	 * Actually load bean definitions from the specified XML file.
	 * @param inputSource the SAX InputSource to read from
	 * @param resource the resource descriptor for the XML file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	 //具体的读取过程是在doLoadBeanDefinitions方法中找到
	 //这里从特定的XML文件中实际载入BeanDefinition的地方
	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			int validationMode = getValidationModeForResource(resource);
			//取得XML的Document对象
			Document doc = this.documentLoader.loadDocument(
					inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
			//启动是对BeanDefinition解析的详细过程,这个解析会使用到Spring的Bean配置规则
			return registerBeanDefinitions(doc, resource);
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (SAXParseException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
		}
		catch (SAXException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"XML document from " + resource + " is invalid", ex);
		}
		catch (ParserConfigurationException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Parser configuration exception parsing XML from " + resource, ex);
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"IOException parsing XML document from " + resource, ex);
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Unexpected exception parsing XML document from " + resource, ex);
		}
	}
	
	
	/**
	 * Register the bean definitions contained in the given DOM document.
	 * Called by <code>loadBeanDefinitions</code>.
	 * <p>Creates a new instance of the parser class and invokes
	 * <code>registerBeanDefinitions</code> on it.
	 * @param doc the DOM document
	 * @param resource the resource descriptor (for context information)
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of parsing errors
	 * @see #loadBeanDefinitions
	 * @see #setDocumentReaderClass
	 * @see BeanDefinitionDocumentReader#registerBeanDefinitions
	 */
	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//得到BeanDefinitionDocumentReader来对XML的BeanDefinition进行解析
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		documentReader.setEnvironment(this.getEnvironment());
		int countBefore = getRegistry().getBeanDefinitionCount();
		//具体解析过程
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}	
	
	/**
	 * Process the given bean element, parsing the bean definition
	 * and registering it with the registry.
	 */
	 //处理BeanDefinition的地方,具体的处理委托给BeanDefinitionParserDelegate来完成,ele对应在Spring BeanDefinition中定义的XML元素
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//BeanDefinitionHolder是BeanDefinition对象的封装类,封装了BeanDefinition,Bean的名字和别名。
		//用他来完成向IoC容器注册。
		//得到这个BeanDefinitionHolder就意味着BeanDefinition是通过BeanDefinitionParserDelegate对XML元素的信息按照Spring的Bean规则进行解析得到的
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
	
	/**
	 * Parses the supplied <code><bean></code> element. May return <code>null</code>
	 * if there were errors during parse. Errors are reported to the
	 * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
	 */
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		//这里取得在<bean>元素中定义的id、name和aliase属性的值
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<String>();
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		String beanName = id;
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isDebugEnabled()) {
				logger.debug("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		//这个方法会引发对Bean元素的详细解析
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						beanName = this.readerContext.generateBeanName(beanDefinition);
						// Register an alias for the plain bean class name, if still possible,
						// if the generator returned the class name plus a suffix.
						// This is expected for Spring 1.2/2.0 backwards compatibility.
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Neither XML 'id' nor 'name' specified - " +
								"using generated bean name [" + beanName + "]");
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}	
	

3BeanDefinition在IoC容器中的注册
如图:registerBeanDefinition的调用关系.jpg


	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		//注册的过程需要synchronized,保证数据的一致性
		synchronized (this.beanDefinitionMap) {
			//检查是否已经存在相同名称的注册,如果已经存在,抛出异常
			Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
			if (oldBeanDefinition != null) {
				if (!this.allowBeanDefinitionOverriding) {
					throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
							"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
							"': There is already [" + oldBeanDefinition + "] bound.");
				}
				else {
					if (this.logger.isInfoEnabled()) {
						this.logger.info("Overriding bean definition for bean '" + beanName +
								"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
					}
				}
			}
			//注册动作,先把名称放到beanDefinitionNames中,然后键值存入beanDefinitionMap
			else {
				this.beanDefinitionNames.add(beanName);
				this.frozenBeanDefinitionNames = null;
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);

			resetBeanDefinition(beanName);
		}
	}	

完成了BeanDefinition的注册,就完成了IoC容器的初始化过程。此时DefaultListableBeanFactory容器中已经建立了整个Bean的配置信息,而这些BeanDefinition已经可以在容器使用了,这些信息就是容器建立依赖反转的基础。



4容器的依赖注入

从AbstractBeanFactory的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 if creating a prototype using explicit arguments to a
	 * static factory method. It is invalid to use a non-null args value in any other case.
	 * @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")
	//这是实际取得Bean的地方,也是触发依赖注入发生的地方
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		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.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//Get the object for the given bean instance, either the bean instance itself or its created object in case of a FactoryBean.
			//完成的是FactoryBean的相关处理,以取得factoryBean的生产结果			
			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.
			//对IoC容器中的BeanDefinition是否存在进行检查,检查是否能在当前的BeanFactory中取得需要的Bean。
			//如果当前工厂取不到,则到双亲BeanFactory中去取;如果当前的双亲工厂取不到,就顺着双亲BeanFactory链一直向上查找。
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			//根绝Bean的名字取得BeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			//获得当前Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取到一个没有任何依赖的Bean为止
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					getBean(dependsOnBean);
					registerDependentBean(dependsOnBean, beanName);
				}
			}

			// Create bean instance.
			//这里通过调用createBean方法创建Singleton bean的实例,这里有一个回调函数getObject,会在getSingleton中带哦用ObjectFactory的createBean。
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					public Object getObject() throws BeansException {
						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);
			}

			//这里是创建prototype bean的地方
			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 '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
						public Object getObject() throws BeansException {
							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);
				}
			}
		}

		// Check if required type matches the type of the actual bean instance.
		//这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean,这个Bean已经是包含了依赖关系的Bean
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type [" +
							ClassUtils.getQualifiedName(requiredType) + "]", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

getBean是依赖注入的起点,之后会调用createBean。
如图:依赖注入的过程.jpg


AbstractAutowireCapableBeanFactory:
	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		// Make sure bean class is actually resolved at this point.
		//这里判断需要创建的bean是否可以实例化,这个类是否可以通过类装载器来载入
		resolveBeanClass(mbd, beanName);

		// Prepare method overrides.
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//如果Bean配置了PostProcessor,那么这里返回是一个proxy
			Object bean = resolveBeforeInstantiation(beanName, mbd);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		Object beanInstance = doCreateBean(beanName, mbd, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

	
	/**
	 * Actually create the specified bean. Pre-creation processing has already happened
	 * at this point, e.g. checking <code>postProcessBeforeInstantiation</code> 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 arguments to use if creating a prototype using explicit arguments to a
	 * static factory method. This parameter must be <code>null</code> except in this case.
	 * @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 Object[] args) {
		// Instantiate the bean.
		//这个BeanWrapper是用来持有创建出来的Bean对象的
		BeanWrapper instanceWrapper = null;
		//如果是isSingleton,先把缓存中的同名Bean清除
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		//由createBeanInstance创建bean
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				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.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		//这里是bean的初始化,依赖注入往往在这里发生,这个exposedObject在初始化处理完以后会返回作为依赖注入完成后的bean
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				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<String>(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和populateBean。
Bean包含的Java对象的生成:
	/**
	 * 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 arguments to use if creating a prototype using explicit arguments to a
	 * static factory method. It is invalid to use a non-null args value in any other case.
	 * @return BeanWrapper for the new instance
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//确定需要创建爱的Bean实例的类可以实例化
		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());
		}
		//使用工厂方法对Bean进行实例化
		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);
			}
		}

		// Need to determine the constructor...
		//使用构造器进行实例化
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		//是有默认的构造器对类进行实例化
		return 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 BeanWrapper for the new instance
	 */
	 //最常用的实例化过程instantiateBean
	 //默认的实例化方式CGLIB:
	 ///** Strategy for creating bean instances */
	//private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					public Object run() {
						return 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);
		}
	}	
提供了两种实例化Java对象方法:一种通过BeanUtils,使用了JVM的反射功能,一种是通过CGLIB。
public class SimpleInstantiationStrategy implements InstantiationStrategy {

	private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<Method>();

	public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (beanDefinition.getMethodOverrides().isEmpty()) {
			//这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化
			Constructor<?> constructorToUse;
			synchronized (beanDefinition.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class clazz = beanDefinition.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
								public Constructor run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			//使用CGLIB进行实例化
			return instantiateWithMethodInjection(beanDefinition, beanName, owner);
		}
	}	
	
Bean对象生成以后,还需要对这些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 BeanWrapper with bean instance
	 */
	protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
		//获得BeanDefinition的各种属性
		PropertyValues pvs = mbd.getPropertyValues();

		if (bw == null) {
			if (!pvs.isEmpty()) {
				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.
		boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}
		//开始进行依赖注入过程
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//对属性进行依赖注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
	
还有就是具体的实现....		


5容器其他相关特性的设计与实现

1ApplicationContext和Bean的初始化及销毁:
AbstractApplicationContext:
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

//Actually performs context closing: publishes a ContextClosedEvent and destroys the singletons in the bean factory of this application context. 
//Called by both close() and a JVM shutdown hook, if any.
doClose()

Spring IoC在对Bean的生命周期进行管理时提供了Bean生命周期各个时间点的回调。
AbstractAutowireCapableBeanFactory:
	/**
	 * Initialize the given bean instance, applying factory callbacks
	 * as well as init methods and bean post processors.
	 * <p>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</code>, 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(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				public Object run() {
					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;
	}
在这个方法中使用了很多invoke。invokeInitMethods--invokeCustomInitMethod	
然后通过method反射调用
	/**
	 * Invoke the specified custom init method on the given bean.
	 * Called by invokeInitMethods.
	 * <p>Can be overridden in subclasses for custom resolution of init
	 * methods with arguments.
	 * @see #invokeInitMethods
	 */
	protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
		String initMethodName = mbd.getInitMethodName();
		final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
				BeanUtils.findMethod(bean.getClass(), initMethodName) :
				ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
		if (initMethod == null) {
			if (mbd.isEnforceInitMethod()) {
				throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
						initMethodName + "' on bean with name '" + beanName + "'");
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("No default init method named '" + initMethodName +
							"' found on bean with name '" + beanName + "'");
				}
				// Ignore non-existent default lifecycle methods.
				return;
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
		}
		
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
				public Object run() throws Exception {
					ReflectionUtils.makeAccessible(initMethod);
					return null;
				}
			});
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
					public Object run() throws Exception {
						initMethod.invoke(bean);
						return null;
					}
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				InvocationTargetException ex = (InvocationTargetException) pae.getException();
				throw ex.getTargetException();
			}
		}
		else {
			try {
				ReflectionUtils.makeAccessible(initMethod);
				initMethod.invoke(bean);
			} 
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}
	
	/**
	 * Make the given method accessible, explicitly setting it accessible if
	 * necessary. The <code>setAccessible(true)</code> method is only called
	 * when actually necessary, to avoid unnecessary conflicts with a JVM
	 * SecurityManager (if active).
	 * @param method the method to make accessible
	 * @see java.lang.reflect.Method#setAccessible
	 */
	public static void makeAccessible(Method method) {
		if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
				&& !method.isAccessible()) {
			method.setAccessible(true);
		}
	}
	
DisposableBeanAdapter:close();
	

2lazy-init属性和预实例化	
在finishBeanFactoryInitialization(beanFactory)方法中,封装了对lazy-init属性的处理,实际的的处理是在DefaultListableBeanFactory这个基本容器的preInstantiateSingletons()方法中完成的。


3FactoryBean的实现
FactoryBean的生产特性是在getBean中起作用。而本身的机制类似于AbstractFactory抽象工厂。

4BeanPostProcessor的实现
这个后置处理器是一个监听器,可以监听容器触发的时间。
在前面的initializeBean方法中有两句代码执行了这个后置处理器:
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

5autowiring、@Autowired
AbstractAutowireCapableBeanFactory的populateBean方法中:
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
	
6Bean的依赖检查
在AbstractAutowireCapableBeanFactory creatBean的过程中检查的


7Bean对IoC容器的感知
某些情况下需要在Bean中直接对IoC容器进行操作,这时候,就需要在Bean中定义对容器的感知,通过特定的aware接口来完成。
ApplicationContextAwareProcessor implements BeanPostProcessor,对一系列的aware回调进行调用。作为依赖注入的一部分,postProcessBeforeInitialization会在initializeBean的实现过程中被调用。


Petalinux 2021.2 下 Qt组件编译报错?手把手教你修改bb文件搞定qt3d/qtquickcontrols2 本文详细解析了Petalinux 2021.2环境下Qt组件(如qt3d、qtquickcontrols2)编译报错的解决方案。通过修改bb文件或使用bbappend文件覆盖,有效解决`petalinux-build --sdk`命令执行时的源码获取失败或哈希校验不匹配问题,并提供验证与调试技巧,帮助开发者快速修复构建流程中断问题。 阅读详情

相关推荐

STM32接入CH340芯片的升级电路及初始化进入升级模式(死机)问题处理

MCU-REST 在 MCU-BOOT0 处于低电平状态下,进行下拉操作,在MCU-REST 与 MCU-BOOT0 恢复正常电平时,将导致MCU死机,MCU-REST 先于 MCU-BOOT0 下拉可解决该问题;MCU-REST 在 上升沿结束时将判断 MCU-BOOT0 的状态,MCU-BOOT0 处于高电平,MCU死机,MCU-BOOT0 处于低电平 MCU 正常;

LuDvei的博客 2491

【Spring】AbstractApplicationContext源码解读

这个类源码一打开,我滴妈有一种我不卷了,我送外卖去了的感觉1500行···· 但是还是对你自己说 坚持坚持再坚持。35岁再送外卖也不迟。 这里我们先看这个抽象类的注释: Abstract implementation of the ApplicationContext interface. Doesn't mandate the type of storage used for configuration; simply implements common context functionality

Anakki的博客 1304

山石网科Hillstone防火墙基础上网配置_CLI命令行(最新版)

山石网科Hillstone防火墙安全网关基础上网基础网络配置_CLI命令行(最新版)

路与肥的博客 1万+

Dubbo 服务无提供者

Dubbo 服务无提供者 总结 检查 Dubbo Admin 控制台,按接口名称查找是否有提供者 检查 Provider 应用代码 检查 dubbo-provider.xml 中是否配置对外的RPC接口 检查 dubbo-provider.xml 中RPC接口的实现类路径配置是否正确,当将实现类配置为RPC接口路径时报错如下 interface not allowed for ...

走在命运的左岸 2030

π_RL:解锁流匹配VLA强化学习后训练的关键技术与实战解析

本文深入解析了π_RL框架如何通过流匹配(flow matching)与强化学习(RL)的结合,解决视觉语言动作模型(VLA)在后训练中的关键挑战。详细介绍了Flow Noise和Flow SDE两大核心技术,以及它们在机器人控制任务中的实战效果,显著提升了模型的性能、数据效率和泛化能力。

weixin_29061531的博客 220

信息化建设项目前期方案编制4:如何画好四张图

这里探讨以下具体的总体设计操作层面的工作。总体设计主要是完成四张图,总体架构(逻辑架构)、应用架构、网络拓扑、系统部署图。对于一些单一的系统,往往总体架构和应用架构可以合一。网络拓扑画好了,系统部署图也可以省略。有些项目还会在这之外,有所谓的技术架构图。对应用系统、数据存储等各个部分各自用的主要技术、服务等,给出总体设计图。但通常来说,这四张图在一个中等规模(200~500万,软件...

Leonardo的博客 4636

java: 无法访问org.springframework.beans.factory.ListableBeanFactory

先记录一下问题 java: 无法访问org.springframework.beans.factory.ListableBeanFactory 找不到org.springframework.beans.factory.ListableBeanFactory的类文件

qq_42898366的博客 1万+

【GameFramework框架内置模块】8、文件系统(File System)

最近好忙,鸽了好久。不能颓废了,继续发力。今天分享的是GF框架的文件系统。首先,引用比较官方的说法:GF的FileSystem虚拟文件系统,使用类似磁盘存储的感念对零散的文件进行集中管理,优化资源加载时产生的内存分配,也可以对资源进行局部片段加载,极大的提升了资源加载的性能。通俗点讲就是,我这个模块就是加载磁盘文件的,优化加载时产生的内存分配。那么,它是怎么优化的呢?

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2452

【异常解决】java: 无法访问org.springframework.boot.SpringApplication的解决方案

拿我自己初始化的这个SpringBoot项目来说,我选择的SpringBoot版本3.0.5,该版本的SpringBoot所需的JDK版本是JDK17,而我本地电脑只安装了一个JDK8的运行环境,所以才会报这个错误。报错信息里所说的类文件版本指的是java class file version,java类文件版本。其实这个该版本号与jdk版本号是存在对应关系,具体来说61.0对应jdk17,52.0对应jdk8。理论上来说,从Spring官网初始化的一个项目,没有添加任何代码,不应该报错。

No8g攻城狮的博客 1万+

NVP6324、NVP6188、NVP6158C的区别详解

根据搜索结果,NVP6324、NVP6188、NVP6158C是Nextchip公司推出的不同型号视频处理芯片,主要区别体现在应用场景、功能特性、接口支持及封装规格等方面。如需进一步技术细节(如寄存器配置或开发支持),可参考具体型号的规格书或联系Nextchip代理商。

小灰灰的博客 3002

搞定最强大模型Gemini学生订阅,白嫖一年,包教包会

白嫖现在最强大模型

BUG猿的博客 2万+

Spring技术内幕(2)Spring FrameWork的核心:IoC容器的实现

本章内容: Spring IoC容器概述、IoC容器系列的设计与实现:BeanFactory和ApplicationContext、IoC容器初始化过程、IoC容器的依赖注入、容器其他相关特性的设计与实现。 2.1 Spring IoC容器概述 2.1.1 IoC容器和依赖反转模式 在面向对象中,对象封装了数据和对数据处理,对象的依赖关系体现在对数据和方法的依赖上。这些依赖关系可以通过把对...

qq_42499188的博客 233

手把手教你学Simulink--基于Simulink的近端策略优化(PPO)路径规划仿真建模

本文详细介绍了如何利用Simulink进行近端策略优化(PPO)路径规划的仿真建模。首先,文章概述了PPO路径规划的特点和挑战,强调了其在连续或离散动作空间问题中的高效性和稳定性。接着,列出了所需的工具和环境,包括MATLAB/Simulink、Reinforcement Learning Toolbox等。随后,文章分步骤详细讲解了从定义任务需求到验证与分析的整个仿真建模过程,包括创建Simulink项目、集成智能体模型、构建环境模型、编写PPO路径规划逻辑、将逻辑集成到Simulink模型中以及最终的验

MHD0815的博客 165

第 2 章:Spring Framework 中的 IoC 容器

在介绍 Spring Framework 的 IoC 容器前,我们有必要先理解什么是“控制反转”。控制反转是一种决定容器如何装配组件的模式。只要遵循这种模式,按照一定的规则,容器就能将组件组装起来。这里所谓的容器,就是用来创建组件并对它们进行管理的地方。它牵扯到组件该如何定义、组件该何时创建、又该何时销毁、它们互相之间是什么关系等——这些本该在组件内部管理的东西,被从组件中剥离了出来。

Binge毕设 2082

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

读《Spring-技术内幕》-第二章:IoC容器的实现-1

第二章: Spring Framework的核心: IoC容器的实现(第一篇总结)博客概要       博客总共总结了2个方面:1是介绍了IoC的概念,2是根据Spring的IoC接口关系图,通过2条设计主线来分析Spring是如何设计和实现IoC容器的?同时也简要的分析了这张IoC接口关系图(详见图2-2)        博客首先介绍了什么是IOC容器?IOC容器可以替我们做什么?为什么需要IO

一只海滩上的贝壳 9197

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring技术内幕——Spring Framework的IOC容器实现(二)

三、IOC容器的初始化过程 IOC容器的初始化时由前面介绍的refresh方法来启动的,这个方法标志着IOC容器的正式启动。这个启动包括BeanDefinition的Resource定位、载入和注册。下面我们将详细分析这三个实现过程,Spring把这三个过程分开,并使用不同的模块来完成,通过这样的设计让用户更加灵活的这三个过程进行剪裁和扩展,定义出最适合自己的IOC容器的初始化过程。 第一个过程

路漫漫,水迢迢 1595

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spring 核心指南(上):IoC 容器与配置方式详解

在Java开发领域,**Spring框架** 是一种极为流行的企业级开源框架,以其轻量、易扩展和模块化的特性受到了广泛的欢迎。Spring框架的核心目标是**简化Java开发**,通过提供基础设施支持,让开发人员专注于业务逻辑的实现。Spring框架的核心模块之一是**Spring IoC(Inversion of Control)容器**,它是实现**依赖注入(DI, Dependency Injection)**的基础。 本文将对Spring框架做一个简要介绍,随后深入探讨**IoC**的概念、Sp

qq_36534560的博客 1405

Spring Framework的核心:IoC容器的实现(1)

Spring 容器是 Spring 框架的核心。容器将创建对象、将它们连接在一起、配置它们并管理它们从创建到销毁的完整生命周期。Spring 容器使用 DI 管理构成应用程序的组件。这些对象称为 Spring Bean。容器通过读取提供的配置元数据来获取关于要实例化、配置和组装哪些对象的指令。配置元数据可以由 XML、Java 注解或 Java 代码表示。下图展示了 Spring 工作原理的高级视图。

鱼干的博客 825

Spring01——Spring简介、Spring Framework架构、Spring核心概念、IOC入门案例、DI入门案例

Spring01——Spring简介、Spring Framework架构、Spring核心概念、IOC入门案例、DI入门案例

后端小白个人学习记录 1591

Spring Framework :IoC 容器的原理与实践

本文深入探讨了Spring框架中控制反转(IoC)容器的核心机制。文章首先分析了传统Java开发模式在对象管理上的局限性,进而阐述了IoC容器如何通过控制反转和依赖注入(DI)实现组件解耦。详细解析了IoC容器的核心组件(BeanFactory和ApplicationContext)及其三阶段工作流程(资源加载、Bean实例化、初始化)。同时介绍了三种配置方式(XML、注解、Java配置)的实践应用,并探讨了Bean作用域、循环依赖解决方案等进阶内容。最后提出了优先使用注解配置、依赖接口等最佳实践建议,帮助

sengminPark的博客 1356

Spring Framework 中的 IoC 容器:实战指南

控制反转是一种软件设计原则,其核心思想是将应用程序的控制权从代码本身分离出来,交给一个外部容器来管理。在传统的编码方式中,对象间的依赖关系通常由对象自身直接创建和管理,这导致了代码之间的紧密耦合。而控制反转则通过将对象的创建和管理委托给容器,实现了对象间的松耦合。控制反转的一个重要实现方式是依赖注入(Dependency Injection)。依赖注入可以通过构造函数、属性或者接口注入的方式,将对象的依赖关系注入到对象中。这种方式极大地提高了代码的灵活性和可测试性。

m0_37643701的博客 766

Spring Framework 入门第一天:掌握核心容器 IOC 与 DI

本文介绍了Spring Framework的核心概念IOC(控制反转)和DI(依赖注入)。IOC将对象创建权交给容器管理,解决代码耦合问题;DI则负责建立Bean间的依赖关系。文章通过创建Maven项目、配置XML文件和获取容器对象等步骤,演示了如何实现IOC容器管理对象。最后指出需要通过DI彻底消除代码中的new操作,实现完全解耦。Spring Framework作为Spring家族的基础,其核心容器是后续学习Spring Boot和Spring Cloud的重要基础。

auspicious349的博客 425

[Spring Framework]核心概念(IOC/DI、IOC容器和Bean)、IOC初次使用

业务层需要调用数据层的方法,就需要在业务层new数据层的对象。如果数据层的实现类发生变化,那么业务层的代码也需要跟着改变,发生变更后,都需要进行编译打包和重部署: 所以,现在代码在编写的过程中存在的问题是:耦合度偏高针对这个问题,该如何解决呢? 我们就想,如果能把框中的内容给去掉,不就可以降低依赖了么,但是又会引入新的问题,去掉以后程序能运行么?答案肯定是不行,因为bookDao没有赋值为Null,强行运行就会出空指针异常。所以现在的问题就是,业务层不想new对象,运行的时候又需要这个对象,该咋办呢?针

十八岁讨厌编程的博客 825

《Java 100 天进阶之路》第73篇:Spring IoC容器(2026版)

Spring全家桶专题开篇之作!IoC(控制反转)是Spring最核心的基石——将对象的创建和依赖管理从代码转移到容器。一文掌握IoC与DI的关系(思想 vs 实现)、BeanFactory vs ApplicationContext(懒加载 vs 预加载)、Bean生命周期五阶段(实例化→属性填充→初始化→使用→销毁)、三种配置方式(XML/注解/Java配置)。附完整代码示例、避坑清单、面试高频考点与追问陷阱。理解了IoC容器,就理解了Spring的"心脏"!

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 8133

Spring 核心技术解析:从 IoC 容器到响应式编程

Spring 框架通过 IoC 容器实现了对象生命周期的精细化管理,借助 AOP 机制实现横切关注点的优雅解耦,其事务管理、Web 开发等核心模块为企业级应用提供了一站式解决方案。Spring 6.x 引入的虚拟线程、AOT 编译等创新特性,进一步强化了框架在云原生时代的竞争力。本文从核心原理到实践应用,系统剖析了 Spring 的技术体系与最佳实践。深入理解 IoC 容器与 AOP 的底层实现合理运用 Spring 6.x 新特性提升性能遵循事务管理、依赖注入等最佳实践。

zqmgx13291的博客 1114

Spring的学习笔记一(Spring Framework的核心:IOC容器的实现)

#Spring IOC的概述 ##IOC容器和依赖反转

XiYoumengshen的博客 306
上一篇: Template Method Pattern
下一篇: 第16条:复合优先于继承
partner4java
博客等级 码龄17年 481粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值