ApplicationContext拓展功能

Spring中的Aware接口及应用场景 Aware接口是Spring Framework中提供的一组标记接口,用于在Bean装配的过程中获取Spring容器中提供的一些核心组件或运行时上下文等信息。通过使用Aware接口,我们可以在Bean实例化和初始化过程中获取到Spring容器中其他组件,方便Bean类实现更复杂的业务逻辑。本文将会一一介绍Spring中各个Aware接口,以及这些接口的主要应用场景。 阅读详情

一、属性设置

对于ApplicationContext,其实例化前必须要设置的就是配置文件的路径--configLocation。例如:

对于非Web环境下的ClasspathXmlApplicationContext,需要通过构造函数或调用setConfigLocation设置配置文件路径;

对于Web环境下的XmlWebApplicationContext,会使用web.xml中配置的contextConfigLocation作为配置文件路径

//另外Web环境下使用的WebXmlApplicationContext还会保存ServletContext对象以及一些Web环境下的参数。

二、刷新上下文

refresh方法基本算是ApplicationContext最重要的方法之一,基本包含了ApplicationContext的大部分功能。需要注意的是,refresh方法并不是在ApplicationContext接口中定义的,而是在其子接口ConfigurableApplicationContext中定义的。下面是refresh的实现(代码位于AbstractApplicationContext):

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 准备刷新的上下文
			prepareRefresh();

			// 初始化BeanFactory,并读取配置文件
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 对BeanFactory进行填充
			prepareBeanFactory(beanFactory);

			try {
				// 模版方法,由子类对初始化好的BeanFactory进行额外的处理
				postProcessBeanFactory(beanFactory);

				// 调用BeanFactoryPostProcessor后处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册Bean处理器
				registerBeanPostProcessors(beanFactory);

				// 初始化Message源,与国际化处理相关
				initMessageSource();

				// 初始化应用消息广播器,并作为一个Bean注册到BeanFactory中
				initApplicationEventMulticaster();

				// 模版方法,交由子类实现,刷新前的特殊处理
				onRefresh();

				// 在注册的bean列表中查找Listener类型的bean,注册到消息广播器中
				registerListeners();

				// 提前初始化单例bean(非惰性的)
				finishBeanFactoryInitialization(beanFactory);

				// 通知生命周期处理器LifecycleProcessor刷新过程,并且发出ContextRefreshEvent事件
				finishRefresh();
			}

			catch (BeansException ex) {
				//log..
				// 销毁已经创建好的bean
				destroyBeans();
				// Reset 'active' flag.
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
			}
		}
	}

刷新的流程为:

  1. 初始化的准备工作,如系统属性或环境变量的准备和验证
  2. 创建BeanFactory,并读取xml配置文件
  3. 对BeanFactory进行功能填充
  4. 通过模版方法模式,交由子类覆盖方法postProcessBeanFactory,对BeanFactory做额外处理
  5. 激活BeanFactory后处理器
  6. 注册拦截Bean创建的Bean处理器
  7. 初始化Message源
  8. 初始化消息广播器
  9. 留给子类初始化其他bean
  10. 将注册的Listener bean注册到消息广播器中
  11. 提前初始化单例bean(非惰性)
  12. 完成刷新,发出ContextRefreshEvent事件,并通知生命周期处理器LifecycleProcessor刷新过程

1、环境准备

主要是做些准备工作,对属性进行初始化和验证工作

	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);
		
		//log...
		// 交由子类覆盖
		initPropertySources();

		// 验证需要的属性是否都已经被放入环境中
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
	}

2、加载BeanFactory

ApplicationContext通过obtainFreshBeanFactory函数创建BeanFactory,自此方法后也就拥有了BeanFactory的所有功能:

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//委托给了refreshBeanFactory方法
		refreshBeanFactory();
		//因为创建BeanFactory实在子类中实现的,所以需要通过getBeanFactory才能获取到实例
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

下面是refreshBeanFactory的实现(位于AbstractRefreshableApplicationContext):

	protected final void refreshBeanFactory() throws BeansException {
		//如果已经创建过BeanFactory,则销毁所有已经创建的Bean并且重新创建BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//实例化
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//设置一些属性
			customizeBeanFactory(beanFactory);
			//加载xml配置文件
			loadBeanDefinitions(beanFactory);
			//将BeanFactory实例设置到ApplicationContext中
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

初始化流程:

  1. 如果已经创建过,则销毁、清理掉以前创建的BeanFactory
  2. 实例化BeanFactory
  3. 定制BeanFactory
  4. 加载xml配置文件

a、实例化BeanFactory

实例化的代码比较简单,直接新建了一个DefaultListableBeanFactory,并且传入父ApplicationContext(如果存在的话)中的BeanFactory作为父BeanFactory,下面是实例化代码:

	protected DefaultListableBeanFactory createBeanFactory() {
		//如果存在父ApplicationContext,会通过它获取父BeanFactory传出构造函数
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

getInternalParentBeanFactory实现:

	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext) ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
	}

如果父ApplicationContext类型是ConfigurableApplicationContext,则获取其中的BeanFactory,否则将父ApplicationContext作为BeanFactory传入。

b、定制BeanFactory

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//allowBeanDefinitionOverriding:是否允许覆盖同名称的不同定义的对象
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//allowCircularReferences:是否允许循环依赖
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

主要是对allowBeanDefinitionOverriding和allowCircularReferences属性进行设置,在AbstractRefreshableApplicationContext中并未对这两个属性进行设置,而是需要由子类来进行配置。

c、加载配置文件

	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 为指定的BeanFactory创建XmlBeanDefinitionReader
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 对XmlBeanDefinitionReader设置环境变量
		beanDefinitionReader.setEnvironment(getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 设置XmlBeanDefinitionReader的属性
		initBeanDefinitionReader(beanDefinitionReader);
		//加载配置文件
		loadBeanDefinitions(beanDefinitionReader);
	}

2、BeanFactory功能填充

对BeanFactory的功能填充是在prepareBeanFactory方法中完成的,再次之前,BeanFactory已经创建好并且完成了对xml配置文件的解析:

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置BeanFactory的ClassLoader为当前Context的ClassLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		//设置BeanFactory的表达式语言处理器,例如对#{bean.xx}调用相关值
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//对bean属性等设置管理的工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 添加PostPrecessor
		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.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 添加PostPrecessor(该PostProcessor功能是对AspectJ的支持)
		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()));
		}

		// 在BeanFactory中注册系统环境Bean
		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());
		}
	}

上面代码中的拓展包括:

  1. 对SpEL(Spring Expression Language)的支持
  2. 对属性编辑器的支持
  3. 增加一些内置类,如EnvironmentAware、MessageSourceAware的信息注入
  4. 设置依赖功能需要忽略的接口
  5. 增加AspectJ的支持
  6. 将环境变量和属性注册的对象注册到BeanFactory中
  7. 注册了一些固定的依赖属性,如BeanFactory、ApplicationContext等

3、激活BeanFactory后处理器

BeanFactoryPostProcessor接口与BeanPostProcessor类似,能够在Bean创建过程中修改bean的定义信息。Spring允许BeanFactoryPostProcessor在容器实例化bean前读取bean定义,并可以修改它。下面是激活的代码:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//激活BeanFactoryPostProcessor的功能委托给了PostProcessorRegistrationDelegate
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		//tempClassLoader为null && BeanFactory包含"loadTimeWeaver"名的bean
		//将loadTimeWeaver封装到一个BeanPostProcessor中
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

PostProcessorRegistrationDelegate中的实现:

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// 存放处理过的BeanFactoryPostProcessor,避免重复添加、处理
		Set<String> processedBeans = new HashSet<String>();

		//BeanDefinitionRegistry的处理
		//因为DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,所以会进入下面的代码
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			/*
			*硬编码注册的后处理器
			*/
			//调用BeanDefinitionRegistryPostProcessor的额外方法
			//将处理器分类保存到registryPostProcessors和regularPostProcessors
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcesso,
				//并在BeanFactoryPostProcessor基础上还定义了postProcessBeanDefinitionRegistry方法
				//所以需要西先调用额外定义的方法
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					//记录常规beanFactoryPostProcessors
					regularPostProcessors.add(postProcessor);
				}
			}

			/*
			*通过配置注册的BeanDefinitionRegistryPostProcessor后处理器
			*/
			//先获取的是后处理器的beanName列表,而不是后处理器的实例
			//Sping会依次处理实现了PriorityOrdered、Ordered接口的后处理器,最后处理剩下的常规后处理器
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// 处理实现了PriorityOrdered接口的后处理器,结果暂存到priorityOrderedPostProcessors
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//排序(通过PriorityOrdered接口)
			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
			//将结果添加到registryPostProcessors
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
			//和上面一样,调用BeanDefinitionRegistryPostProcessor中自己定义的方法postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

			//处理实现了Ordered接口的后处理器,结果暂存到orderedPostProcessors(处理过程和PriorityOrdered接口的类似)
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				//该PostProcessor还未被处理过 && 实现了Ordered接口
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(beanFactory, orderedPostProcessors);	//排序(通过Ordered接口)
			//结果添加到registryPostProcessors
			registryPostProcessors.addAll(orderedPostProcessors);
			//和上面一样,调用BeanDefinitionRegistryPostProcessor中自己定义的方法postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

			// 最后,处理剩下的BeanDefinitionRegistryPostProcessor
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				//获取所有BeanDefinitionRegistryPostProcessor类型的bean
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					//如果还未被处理过
					if (!processedBeans.contains(ppName)) {
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
						//将结果添加到registryPostProcessors
						registryPostProcessors.add(pp);
						processedBeans.add(ppName);
						//调用BeanDefinitionRegistryPostProcessor中自己定义的方法postProcessBeanDefinitionRegistry
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}

			// 调用BeanFactoryPostProcessor中定义的postProcessBeanFactory方法
			//(前面调用的都是registryPostProcessors,定义在BeanDefinitionRegistryPostProcessor中)
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 调用BeanFactoryPostProcessor中定义的postProcessBeanFactory方法.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
		/*
		*上面代码已经将硬编码的BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和配置中的BeanDefinitionRegistryPostProcessor分类处理了
		*后面代码需要处理配置中的BeanFactoryPostProcessor类型的后处理器
		*/
		// 获取通过配置注册的BeanFactoryPostProcessor后处理器的beanName列表
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
				
		//Spring还是会将处理器分为排序和不需要排序两类,分别处理
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			//过滤掉处理过的,剩下的就是配置中的BeanFactoryPostProcessor
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			//分类添加到不同列表
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 对实现了PriorityOrdered的处理器排序,并依次应用BeanFactoryPostProcessor
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 对实现了Ordered的处理器排序,并依次应用BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(beanFactory, orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 应用常规BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 因为可能修改了Bean的定义信息。所以需要清除缓存的merged beanDefinitions
		beanFactory.clearMetadataCache();
	}
	
	

Spring中少有的长代码。。

上面代码功能就是应用BeanFactoryPostProcessor后处理器。但是,由一点比较特特殊的是BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,并且还定义了一个postProcessBeanDefinitionRegistry方法(BeanFactoryPostProcessor中只定义了一个方法-postProcessBeanFactory)。所以,在应用BeanFactoryPostProcessor后处理器中的postProcessBeanFactory方法前,需要先调用BeanDefinitionRegistryPostProcessor中的方法。

另外,向ApplicationContext中添加BeanFactoryPostProcessor的方法由两种:一是通过context直接调用addBeanFactoryPostProcessor硬编码添加;二是通过配置文件或@Component等注解向BeanFactory中注册一个BeanFactoryPostProcessor类型的bean。Spring针对两种配置,需要分类处理。

如果后处理器继承了PriorityOrdered或Ordered接口,Spring会优先将这些处理器排序后依次调用。(对于硬编码添加和配置添加的都会进行排序,但是对于Spring3以前的版本,并不会对硬编码方式添加的后处理器进行排序)

调用顺勋:PriorityOrdered --> Ordered --> 常规处理器

处理流程如下:

  1. 对BeanDefinitionRegistryPostProcessor的特殊处理,调用其postProcessBeanDefinitionRegistry方法
  2. 处理硬编码的所有BeanFactoryPostProcessor后处理器以及通过配置注册的BeanDefinitionRegistryPostProcessor后处理器:按照 PriorityOrdered --> Ordered --> 常规处理器 的顺序应用BeanFactoryPostProcessor中的方法
  3. 处理剩下的通过配置注册的BeanFactoryPostProcessor。因为BeanDefinitionRegistryPostProcessor已经在上一步中处理过了,这一步只需要按照 PriorityOrdered --> Ordered --> 常规处理器 的顺序应用剩下的BeanFactoryPostProcessor

3、注册BeanPostProcessor

Spring的大部分功能都是通过BeanPostProcessor来拓展添加的,在这一步,Spring会将BeanFactory中所有的BeanPostProcessor类型的bean注册为后处理器,具体代码如下:

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//真正注册的功能委托给了PostProcessorRegistrationDelegate
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

PostProcessorRegistrationDelegate中的实现:

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		//获取BeanFactory中所有BeanPostProcessor类型的beanName
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		//注册一个特殊的BeanPostProcessor:BeanPostProcessorChecker
		//该后处理器的功能就是如果一个bean在BeanPostProcessor还没全部加载完成的时候创建,Spring会打印一条info级别的信息,
		//打印信息表明该bean并没有被所有BeanPostProcessor处理
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 根据是否支持排序分类处理BeanPostProcessor
		// 处理顺序为PriorityOrdered -> Ordered -> 常规后处理器
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		//内部使用的BeanPostProcessor(如果后处理器类型是MergedBeanDefinitionPostProcessor的话,会放入该列表)
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 注册继承自PriorityOrdered接口的BeanPostProcessor
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 注册继承自Ordered接口的BeanPostProcessor
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(beanFactory, orderedPostProcessors);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 注册剩下的常规BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		//最后重新注册一遍内部BeanPostProcessor(会将这些BeanPostProcessor放在列表最后)
		sortPostProcessors(beanFactory, internalPostProcessors);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 会注册一个特殊的BeanPostProcessor
		// ApplicationListenerDetector的功能是将类型是 ApplicationListener 的bean添加到事件广播器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

上述代码处理流程为:

  1. 注册BeanPostProcessorChecker。该BeanPostProcessor功能是:如果一个bean在BeanPostProcessor还没全部加载完成的时候创建,Spring会打印一条info级别的信息,该信息内容表明该创建的bean并未被所有BeanPostProcessor处理
  2. 查找出BeanFactory中所有BeanPostProcessor的bean,并作为BeanPostProcessor注册到BeanFactory中。同时支持排序接口,注册顺序为:PriorityOrdered -> Ordered -> 常规后处理器。比较特殊的是,MergedBeanDefinitionPostProcessor类型的后处理器是作为Spring内部使用的,所以会在添加到BeanPostProcessor列表末尾
  3. 注册ApplicationListenerDetector。该BeanPostProcessor功能:在创建bean的时候,如果bean类型是ApplicationListener ,会被添加到事件广播器

4、初始化消息资源

	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果配置了messageSource,就将其实例保存到this.messageSource中
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			//log...
		}
		else {
			// 如果用户没有定义,使用默认的DelegatingMessageSource作为messageSource
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

5、初始化ApplicationEventMulticaster

事件广播器作用就是发布各种事件,然后由ApplicationListener处理(前面注册BeanPostProcessor中专门有一个ApplicationListenerDetector来注册用户配置的ApplicationListener),初始化并注册的代码如下:

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果BeanFactory中包含名称为“applicationEventMulticaster”的bean,就使用该bean作为事件广播器
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			// log...
		}
		else {
			//使用默认的SimpleApplicationEventMulticaster作为广播器,并注册到BeanFactory中
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			//log...
		}
	}

6、注册监听器

在上一步初始化好事件广播器后,Spring接着会向其添加监听器:

	protected void registerListeners() {
		// 将前面硬编码方式注册的监听器添加到广播器中
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		//配置文件或者注解注册的监听器处理
		//为了使监听器得到后处理器的加工,这里并没有实例化监听器,而是保存beanName
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 发布earlyApplicationEvents的事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

7、初始化非延迟单例

除了初始化单例bean以外,这一步还会完成一部分初始化BeanFactory的功能,包括:ConversionService的设置、冻结配置、设置EmbeddedValueResolver、初始化LoadTimeWeaverAware,源码如下:

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 初始化conversionService,如果存在的话
		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));
		}

		// 注册一个默认的StringValueResolver到embeddedValueResolver
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}

		// 提前初始化 LoadTimeWeaverAware 
		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);

		// 冻结bean定义,表明注册的bean定义将无法再次被修改
		beanFactory.freezeConfiguration();

		// 初始化剩余的非延迟加载单例
		beanFactory.preInstantiateSingletons();
	}

下面是初始化非延加载单例的源码:

	public void preInstantiateSingletons() throws BeansException {
		//log...
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// 遍历beanNames,初始化其中的非惰性单例bean
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//非Abstract || 单例 || 非惰性
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//FactoryBean类型bean的处理
				if (isFactoryBean(beanName)) {
					//对于普通FactoryBean类型的bean,Spring会初始化其对应的FactoryBean,并不会初始化实际的bean
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					//对于SmartFactoryBean类型并且isEagerInit返回true的bean,Spring会初始化真正的bean
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					//普通bean直接调用getBean初始化
					getBean(beanName);
				}
			}
		}
  • 对于FactoryBean,Spring会提前初始化其FactoryBean;如果类型是SmartFactoryBean并且isEagerInit 返回true(表示需要立即初始化),Spring才会初始化其真正的bean单例
  • 对于普通bean,Spring会直接调用getBean进行初始化

8、finnishRefresh

在完成刷新上下文后,Spring会通知Lifecycle调用其start方法(销毁时会调用stop方法),进行生命周期管理;并且发布刷新完成的事件:

	protected void finishRefresh() {
		// 初始化lifecycleProcessor
		initLifecycleProcessor();

		// 通知lifecycleProcessor
		getLifecycleProcessor().onRefresh();

		// 发布ContextRefreshedEvent事件
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}
	
  1. 初始化生命周期管理器lifecycleProcessor
  2. 通知Lifecycle类型的bean,调用其start方法(ApplicationContext销毁时会调用其stop方法)
  3. 发布ContextRefreshedEvent事件

至此,完成了上下文的刷新。

总结

ApplicationContext继承了BeanFactory相关的接口,所以具备BeanFactory的所有功能,在此之上,ApplicationContext拓展的功能有:

  1. 注册StandardBeanExpressionResolver对SpEL(Spring Expression Language)的支持
  2. 注册ResourceEditorRegistrar,对属性编辑器的支持
  3. 激活BeanFactoryPostProcessor功能,实例化Bean前修改BeanFactory的状态
  4. 添加了一些内置的BeanPostProcessor,并且将用户配置的BeanPostProcessor注册到BeanFactory中
  5. 增加AspectJ的支持
  6. 增加了几个Aware接口的支持,如:EnvironmentAware、ApplicationContextAware、MessageSourceAware等
  7. MessageSource消息源的支持,用于国际化
  8. 事件广播器、监听器的支持
  9. Lifecycle接口的支持,用于bean的生命周期管理

 

 

 

 

S4 codingblock增加客户化字段的一些小问题 今天使用codingblock增加了两个客户化字段后(S4版本),查看常用的几个表 ACDOCA BSEG 等等两个客户化字段安静的出现在表内,以为没有问题了 。结果后来MM那边查看物料凭证时程序直接dump,后来开发查明原因居然是因为财务增加的这两个增强字段的原因。 报错如下图所示: 主要是因为增加了字段后,更新了后台表,但是没有自动更新到视图。就是MSEG表增加了这两个字段,但是呢他对应的视图NSDM_V_MSEG没有增加,导致两边的结构不一致。 所以要解决这个问题,只能在视图NSDM_V_MSEG增 阅读详情

相关推荐

别再手动算LLC了!用Mathcad 15分钟搞定谐振参数与增益曲线(附已验证产品案例)

本文详细介绍了如何利用Mathcad在15分钟内高效完成LLC谐振变换器的参数计算与增益曲线绘制。通过对比传统工具,突出Mathcad在自然数学表达、实时单位换算和动态参数关联方面的独特优势,帮助电源工程师大幅提升设计效率。文章还提供了已验证的产品案例和实用模板,助力工程师快速掌握谐振参数优化技巧。

weixin_42548888的博客 546

AbstractApplicationContext的refresh方法

AbstractApplicationContext的refresh方法 文章目录AbstractApplicationContext的refresh方法prepareRefreshobtainFreshBeanFactory()prepareBeanFactory()postProcessBeanFactory(beanFactory)invokeBeanFactoryPostProcessors(beanFactory)registerBeanPostProcessors(beanFactory);in

coder_zf的博客 1713

基于微信小程序的垃圾分类系统,附源码

垃圾分类小程序管理员功能有个人中心,管理员管理,意见反馈管理,视频类型管理,垃圾类型管理,新闻类型管理,论坛信息管理,环保视频管理,环保知识管理,垃圾信息管理,环保新闻管理,用户管理,知识问答试卷管理,试题管理,测试管理,轮播图管理。用户可以在微信小程序上面注册登录,查看各种环保信息和垃圾信息,还可以参加知识问答等操作。垃圾分类小程序的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。

Java徐师兄的博客 2074

ApplicationContext之功能扩展

接这上篇文章分析,上篇文章分析到创建好beanFactory,Spring也已经完成对配置文件的解析,ApplicationContext也是在这个基础上进行展开的. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置 beanFactory的classLoader为当前context的classLoader beanFactory.setBeanClassLoader(getC

qq_40708942的博客 268

汽车ECU诊断入门:手把手教你用UDS协议(ISO14229)读取和清除故障码

本文详细介绍了如何使用UDS协议(ISO14229)进行汽车ECU诊断,包括故障码读取与清除的完整流程。从诊断环境搭建、UDS协议基础到实战案例分析,手把手教你掌握0x19诊断服务、安全访问机制等核心技能,适用于汽车电子工程师和诊断开发人员。

weixin_33701251的博客 454

一文看懂英伟达A100、H100、A800、H800、H20

想要Deepseek私有化部署吗?无论是训练大型AI模型,还是进行高性能计算(HPC),还是Deepseek私有化部署,都需要强大的GPU支持。而英伟达(NVIDIA)作为全球领先的AI芯片制造商,推出了一系列高性能GPU,包括等,广泛应用于AI训练、推理、科学计算等领域。如果想搭建一个属于自己的算力中心,该如何选择合适的GPU?本文将带你详细了解这些GPU的特性,并指导你如何搭建算力中心。一、英伟达算力GPU系列解析1. A100:数据中心AI计算的奠基石:Ampere:6912:432。

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 2万+

Spring中修改allowBeanDefinitionOverriding和allowCircularReferences属性的两种方式

allowBeanDefinitionOverriding属性含义 设置是否允许通过注册具有相同名称的不同定义来覆盖bean定义,并自动替换前者。否则,将引发异常。默认值为“true”。 allowCircularReferences属性含义 设置是否允许bean之间的循环引用并自动尝试解析它们。 默认值为“true”。关闭此选项可在遇到循环引用时引发异常,完全不允许循环引用。 循环依赖应该都比较了解,主要看看allowBeanDefinitionOverriding。 public class TestS

自律使我自由 9629

在摩尔线程 MTT S80 上使用 Ollama 进行 DeepSeek R1 蒸馏版模型推理

本文主要介绍了如何在摩尔线程 MTT S80 上通过 Ollama 快速完成DeepSeek R1 蒸馏系列模型的推理。

摩尔线程blog中心 3597

ApplicationContext--容器的功能扩展

ApplicationContext--容器的功能扩展

Xjzzon的博客 366

Camera HAL 多线程管理详解

本文摘要:Camera HAL 采用双线程管理体系(CAMX与CHI-CDK)实现高效并发处理。CAMX ThreadManager负责HAL内部及框架交互,采用线程池+任务调度机制,将节点处理、回调等封装为Job异步执行;CHI ThreadManager专注于OEM定制逻辑,支持异步/同步两种作业模式。两套系统通过函数指针解耦但共享地址空间,共同实现硬件流水线的强实时性。文章详细解析了两者的类层次架构、核心数据结构及典型应用场景,并提供了问题排查的代码切入点,为Camera HAL开发与性能优化提供指导

DU_YULIN的博客 56

Redhawk: dynamic ir drop分析(Clock Buffer Clustering)

在dynamic分析中,ir drop问题多出现在三种情况下,缺power mesh,缺power switch,clock cell过于密集。 前两种情况通过选中具体instance查看min res path都比较容易分析出来,而且大部分问题都出现在channel里,这里不多做赘述。 clock cell过于密集这是观察结果,缺少报告支持,这里分享一下分析方法。 首先,选中压降超过signoff标准的instance,(Results->List of Worst Instance DVD中

m0_61544122的博客 5267

Spring源码阅读(四)—容器的功能拓展ApplicationContext

ApplicationContext和BeanFactory都用于Bean的加载,ApplicationContext包含BeanFactory的所有功能,创建的上下文环境是BeanFactory的功能拓展. 个人主页:tuzhenyu’s page 原文地址:Spring源码阅读(四)—容器的功能拓展ApplicationContext (0) ApplicationCont

tuzhenyu的博客 397

YOLOv11目标检测模型性能评价指标详解,涉及混淆矩阵、F1-Score、IoU、mAP、参数量、计算量等,一文打尽所有评价指标

本文主要讲解的是计算机视觉网络模型的性能评价指标,这是每一篇论文中都需要展示的内容。熟悉每一个评价指标也能够帮助我们在训练和改进模型过程中,更好的观察模型的变化效果。

Limiiiing的博客 8410

Spring源码之容器的功能拓展-ApplicationContext

容器的功能拓展一、解析预备 刷新上下文环境 例如对系统属性或者环境变量进行校验和准备二、初始化 BeanFactory 并进行 Xml 配置文件的读取三、对BeanFactory 各种功能填充四、激活以及注册各种 BeanFactoryPostProcessor 后处理器五、注册后处理器 BeanPostProcessor后续环节 PS * 本文代码基本为伪代码,注释为个人理解,水平有限,如有谬误,感谢指正。 关于spring的容器,除了BeanFactory以及它的默认实现类XmlBeanFactory

bokerr的博客 249

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Spring之ApplicationContext的拓展功能

      相对于BeanFactory来说,ApplicationContext除了提供BeanFactory的所有功能外,还有一些其他的功能,主要包括国际化支持、资源访问、事件传递。下面将讲解ApplicationContext在BeanFactory的基本功能之外的功能。 1.国际化支持 简介      国际化的英文为Internationalization,这个也太长了,所以它又称为...

猎户星座 1114

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Spring 源码学习~12、容器的拓展功能简介

Spring 源码学习

戴泽王的博客 777

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

《Spring源码深度解析 郝佳 第2版》ApplicationContext

往期博客: 《Spring源码深度解析 郝佳 第2版》容器的基本实现与XML文件的加载 《Spring源码深度解析 郝佳 第2版》XML标签的解析 《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决 往期博客分析了BeanFactory接口以及他的默认实现类XmlBeanFactory BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beanFactory.xml")); 接下来分析另外一个高级拓

xiaosi的博客 2402

Spring 4.x IOC介绍(四.BeanFactory 、ApplicationContext、WebApplicationContext——总结)

前面对BeanFactory 、ApplicationContext、WebApplicationContext分别进行了分析,下面进行一下总结。 BeanFactory 继承体系: BeanFactory作为一级接口,其子接口有HierarchicalBeanFactory、ConfigurableBeanFactory等。 作用: 初始化: ApplicationContext...

都让你们叫老了的博客 364

Spring是如何实现ApplicationContext应用上下文

但是只做到这一步还是不够的,我们需要解析XML文件就需要获取到文件的路径,这个路径的获取通过上面的示例也能看出来,是通过构造方法创建的,那我我们就还需要一个用于获取路径的类实现AbstractXmlApplicationContext同时实现获取路径的方法。当中调用的都是抽象方法,在这里我们实际上就只是定义一个模版,规范解析的步骤,至于具体如何实现就需要根据我们的需求了。也就是初始化Bean的方法当中有些逻辑是共通的,不管我们定义何种解析方法都需要用到这些东西,那么我们就可以在这里进行进一步的抽取。

几许的博客 960

第一章 容器与Bean

Spring 源码阅读系列:容器与Bean

m0_73879914的博客 1175

[Learning]《Spring源码深度解析》第六章笔记

0.What’s this? 这是一篇关于《Spring源码深度解析》的笔记 第六章 容器的功能扩展 除了XmlBeanFactory,Spring中还提供了另一个接口ApplicationContext,用于扩展BeanFactory的现有功能。 // 使用BeanFactory BeanFactory bf = new XmlBeanFactory(new ClassPathResource("xxx.xml")); // 使用ApplicationContext ApplicationContext

Lawrence 303

dubbo源码解析-spi(三)

Dubbo源码解析系列文章均来自肥朝简书 前言 在上一篇的末尾,我们提到了dubbo的spi中增加了IoC和AOP的功能.那么本篇就讲一下这个增加的IoC,spi部分预计会有四篇,因为这东西实在是太重要了.温故而知新,我们先来回顾一下,我们之前都讲了什么. spi(1) 主要讲了spi的基本概念,简单的入门,并以spi为线索讲解了双亲委托模式的弊端以及解决方案 spi(2) 主...

Franco的博客 212

Spring中的容器接口

介绍spring中的容器接口

sahuid的博客 1238

【Spring专题】Spring之底层架构核心概念解析

本节课的内容,是后续看Spring源码所必备的概念、类精讲,防止后续看源码的过程中,遇到不会的、看不懂的还得单独跳出来学习。所以,大家好好理解一下这些概念,可以大大地帮助后学源码阅读。另外还有一点需要特别声明接口的作用,有时候是用来约束、规范行为的。像Spring这种优秀的源码,更是会按照接口说明执行。所以,通过看接口注释,可以帮我们理解某个类的能力!切记!切记!切记!切记!切记!切记!BeanPostProcessor,直译为:Bean的后置处理器(

qq_32681589的博客 2929

Java开发框架之Spring源码解析

前言: 作为一个后台java开发,我们接触过很多开源框架。 从最初的webwork,struts到现在最流行的spring,我们会发现这些框架发展都是朝着简化编程,多元化拓展的方向发展的。 spring作为其中的翘楚者,依赖注入,控​​java培训​​制反转,支持配置文件,注解开发,第三方模块轻量接入,比如JDBC,Log,Cache等等。 慢慢的经过发展又出现了更加简便的SpringBoot-约定优于配置的最佳实践者。 给春天穿上靴子,极大的提高开发效率,借助maven工具,把以前搭建sprin

m0_58371965的博客 249

ApplicationContext功能与设计原理

1.ApplicationContext功能 在Spring中,系统已经为用户提供了许多已经定义好的容器实现,而不需要开发人员事必躬亲。相比那些简单拓展BeanFactory的基本IoC容器,开发人员常用的ApplicationContext除T能够提供前面介绍的容器的基本功能外,还为用户提供了附加服务,可以让客户更方便地使用。所以说,ApplicationContext是一个高级形态意义的I...

锋子 643
上一篇: Web容器整合ApplicationContext源码
下一篇: Spring AOP源码解析(一)Advisor获取
finalcola
博客等级 码龄9年 37粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值