SpringIOC源码阅读笔记(10)

保姆级教程:在LKD3588开发板上为RK3588添加SC2210摄像头驱动(含完整DTS配置) 本文提供了一份详细的教程,指导如何在LKD3588开发板上为RK3588处理器添加SC2210摄像头驱动,包括完整的DTS配置和内核编译步骤。教程涵盖了环境准备、驱动文件添加、DTS配置详解、内核编译与烧录、驱动测试以及常见问题排查,帮助开发者快速实现SC2210传感器在RK3588平台上的集成与优化。 阅读详情

分析完BeanFactory容器的加载,接下来看一下更复杂的容器ApplicationContext的加载,这个容器也是我们目前使用比较多的容器。跟BeanFactory比起来,ApplicationContext有如下区别:
1.继承 MessageSource,提供国际化的标准访问策略。
2.继承 ApplicationEventPublisher ,提供强大的事件机制。
3.扩展 ResourceLoader,可以用来加载多个 Resource,可以灵活访问不同的资源。
4.对 Web 应用的支持。
同样的可以从一行代码开始分析:
ApplicationContext bs = new ClassPathXmlApplicationContext(“beanFactoryTest.xml”);
看看Applicationcontext的UML图:
在这里插入图片描述
以及ClassPathXmlApplicationContext在这里插入图片描述
首先是ClassPathXmlApplicationContext的构造函数:

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	//支持多个配置文件已数组方式同时传入
		this(new String[] {configLocation}, true, null);
	}
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		//(1)设置父类
		super(parent);
		//(2)设置配置文件地址
		setConfigLocations(configLocations);
		//(3)刷新
		if (refresh) {
			refresh();
		}
	}

(1)super(parent);实现是在AbstractApplicationContext,有属性private ApplicationContext parent;
(2)setConfigLocations(configLocations);实现是在AbstractRefreshableConfigApplicationContext:

public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			//将参数一个个设置进成员变量private String[] configLocations;
			for (int i = 0; i < locations.length; i++) {
			//如果含有特殊字符例如${var},resolvePath会搜索匹配的系统变量并且替换
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

(3)refresh() 实现是在AbstractApplicationContext

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//准备刷新的上下文环境
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//初始化BeanFactory,并且进行XML文件读取
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//对beanFactory进行各种功能填充
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//子类覆盖方法做额外的处理
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//激活各种BeanFactory处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册Bean处理器
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//初始化Message源
				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.
				//注册监听器
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//初始化剩下的单例(非惰性)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//完成刷新过程
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

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

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

在刷新这个环节做了很多事情,下面一个个分析以上的方法:
1.环境准备prepareRefresh();

protected void prepareRefresh() {
//开始时间
		this.startupDate = System.currentTimeMillis();
		//没有关闭
		this.closed.set(false);
		//活跃状态
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment
		//空实现,留给子类覆盖
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		//对属性进行必要的验证
		getEnvironment().validateRequiredProperties();

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

2.加载BeanFactory,实现在AbstractApplicationContext

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//初始化BeanFactory,并且从xml中读取信息
		refreshBeanFactory();
		//获取BeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

refreshBeanFactory,方法实现在AbstractRefreshableApplicationContext

	@Override
	protected final void refreshBeanFactory() throws BeansException {
	//如果已经有BeanFactory,就摧毁beans并且关闭BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//序列化指定的id
			beanFactory.setSerializationId(getId());
			//定制BeanFactory
			customizeBeanFactory(beanFactory);
			//初始化DocumentReader,进行XML文件读取及解析
			loadBeanDefinitions(beanFactory);
			//绑定成员变量
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
//将所有实例化的bean销毁
protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}
	@Override
	public void destroySingletons() {
		super.destroySingletons();
		//1.删去DefaultListableBeanFactory中manualSingletonNames
		this.manualSingletonNames.clear();
		//删去allBeanNamesByType和singletonBeanNamesByType
		clearByTypeCache();
	}
		@Override
	public void destroySingletons() {
		super.destroySingletons();
		//删去FactoryBeanRegistrySupport中的factoryBeanObjectCache
		this.factoryBeanObjectCache.clear();
	}
	//最后清空DefaultSingletonBeanRegistry中的map
		public void destroySingletons() {
		if (logger.isDebugEnabled()) {
			logger.debug("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			destroySingleton(disposableBeanNames[i]);
		}

		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();

		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}
@Override
//如果在AbstractRefreshableApplicationContext有绑定的beanFactory,就解除绑定。
	protected final void closeBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory != null) {
				this.beanFactory.setSerializationId(null);
				this.beanFactory = null;
			}
		}
	}

创建BeanFactory

	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

指定id,将applicationContext的id指定给BeanFactory的serializationId

	public void setSerializationId(@Nullable String serializationId) {
		if (serializationId != null) {
			serializableFactories.put(serializationId, new WeakReference<>(this));
		}
		else if (this.serializationId != null) {
			serializableFactories.remove(this.serializationId);
		}
		this.serializationId = serializationId;
	}

定制BeanFactory,增加了是否允许覆盖是否允许扩展

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

加载BeanDefinition,实现在AbstractXmlApplicationContext

	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.‘’
		//给指定的BeanFactory创建XmlBeanDefinitionReader
		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);
	}
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
	//得到xml资源
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		//得到xml地址
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

3.功能扩展
接下来进入prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		//将beanFactory的classLoader设置成当前context的classLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		//增加SPEL解析器,这个是在调用AbstractAutowireCapableBeanFactory类的applyPropertyValues来完成功能,使用的是beanExpressionResolver的evaluate
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//增加propertyEditor
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		//添加ApplicationContextAwareProcessor
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//忽略几个自动装配接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		//设置自动装配的特殊规则
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		//添加检测内部beans的后处理器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 增加对AspectJ的支持
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		//添加默认的系统变量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());
		}
	}

添加属性注册编辑器
这个步骤的根源得追溯到initBeanWrapper方法,这时候会调用ResourceEditorRegistrar的registerCustomEditors。

	protected void initBeanWrapper(BeanWrapper bw) {
		bw.setConversionService(getConversionService());
		registerCustomEditors(bw);
	}
//beanWrapper继承PropertyEditorRegistry,所以它也是一个registry
protected void registerCustomEditors(PropertyEditorRegistry registry) {
		PropertyEditorRegistrySupport registrySupport =
				(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
		if (registrySupport != null) {
			registrySupport.useConfigValueEditors();
		}
		if (!this.propertyEditorRegistrars.isEmpty()) {
		//遍历在AbstractBeanFactory注册的propertyEditorRegistrars中的PropertyEditorRegistrar,逐个调用registrar.registerCustomEditors(registry)方法
			for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
				try {
					registrar.registerCustomEditors(registry);
				}
				catch (BeanCreationException ex) {
					Throwable rootCause = ex.getMostSpecificCause();
					if (rootCause instanceof BeanCurrentlyInCreationException) {
						BeanCreationException bce = (BeanCreationException) rootCause;
						String bceBeanName = bce.getBeanName();
						if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
							if (logger.isDebugEnabled()) {
								logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
										"] failed because it tried to obtain currently created bean '" +
										ex.getBeanName() + "': " + ex.getMessage());
							}
							onSuppressedException(ex);
							continue;
						}
					}
					throw ex;
				}
			}
		}
		if (!this.customEditors.isEmpty()) {
			this.customEditors.forEach((requiredType, editorClass) ->
					registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
		}
	}

接下来我们需要知道AbstractBeanFactory中的propertyEditorRegistrars是哪来的。其实就是我们最关注的那行代码:
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	@Override
	public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
		Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
		//将ResourceEditorRegistrar加入了propertyEditorRegistrars
		this.propertyEditorRegistrars.add(registrar);
	}

调用了ResourceEditorRegistrar的registerCustomEditors

@Override
	public void registerCustomEditors(PropertyEditorRegistry registry) {
		ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
		doRegisterEditor(registry, Resource.class, baseEditor);
		doRegisterEditor(registry, ContextResource.class, baseEditor);
		doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
		doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
		doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
		doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
		doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
		doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));

		ClassLoader classLoader = this.resourceLoader.getClassLoader();
		doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
		doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
		doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));

		if (this.resourceLoader instanceof ResourcePatternResolver) {
			doRegisterEditor(registry, Resource[].class,
					new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
		}
	}

逐个调用doRegisterEditor

	private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
		if (registry instanceof PropertyEditorRegistrySupport) {
			((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
		}
		else {
			registry.registerCustomEditor(requiredType, editor);
		}
	}
	@Override
	public void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor) {
		registerCustomEditor(requiredType, null, propertyEditor);
	}
	@Override
	public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {
		if (requiredType == null && propertyPath == null) {
			throw new IllegalArgumentException("Either requiredType or propertyPath is required");
		}
		if (propertyPath != null) {
			if (this.customEditorsForPath == null) {
				this.customEditorsForPath = new LinkedHashMap<>(16);
			}
			this.customEditorsForPath.put(propertyPath, new CustomEditorHolder(propertyEditor, requiredType));
		}
		else {
			if (this.customEditors == null) {
				this.customEditors = new LinkedHashMap<>(16);
			}
			//最后面追踪到会把这个类型和对应的解析器放到PropertyEditorRegistrySupport的customEditors的map中
			this.customEditors.put(requiredType, propertyEditor);
			this.customEditorCache = null;
		}
	}

ok,属性编辑器就解析完毕了,当输入的数值需要解析时会找到对应的解析器。
接下来是beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
后处理器比较熟悉,主要了解下ApplicationContextAwareProcessor这个处理器,其中后置处理没有实现,看看前置处理:

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}
//spring为了实现了以下接口的bean在初始化后提供了对应注入
private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

所以就有了下一步忽略对应的接口。而后也必不可少的会有注册以来的功能。

4.激活各种BeanFactory处理器,注意是激活。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

下面会涉及两种BeanFactoryPostProcessor,BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor,调用顺序是BeanDefinitionRegistryPostProcessor优先于BeanFactoryPostProcessor执行,BeanFactoryPostProcessor优先于bean实例化执行。

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
		//对于BeanDefinitionRegistry类型的处理
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//创建两个list,分别是常规后处理器以及注册处理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
			//遍历工厂后处理器
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
							//调用postProcessBeanDefinitionRegistry方法并且将其添加到list
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
				//不调用方法,直接添加到对应list
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// 用于保存当前处理的 BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 首先处理实现了 PriorityOrdered (有限排序接口)的 BeanDefinitionRegistryPostProcessor
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 加入registryProcessors集合
			registryProcessors.addAll(currentRegistryProcessors);
			// 调用所有实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry()
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 清空,以备下次使用
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 其次,调用是实现了 Ordered(普通排序接口)的 BeanDefinitionRegistryPostProcessors
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 最后调用其他的 BeanDefinitionRegistryPostProcessors
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 如果不是 BeanDefinitionRegistry 只需要调用其回调函数(postProcessBeanFactory())即可
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 这里同样需要区分 PriorityOrdered 、Ordered 和 no Ordered
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			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);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}
【通信协议】GATT 与 BLE HID 工作原理详解 详细介绍BLE HID 跟GATT工作原理与两者的交互关系 阅读详情

相关推荐

智能车数字图像处理算法入门及C语言实现

智能车图像的最最基本入门算法介绍及C语言实现,二值化 - 特征识别 - 补线 - 中心巡线 - 偏差曲率计算。

不想随波逐流的大学生一枚,我们每个人都在努力奔跑 5110

Spring源码解析-PropertyEditor

PropertyEditor最早用于Swing编程中,在Spring中主要被用于xml内value的转换和mvc中参数值得转换。 Spring容器在applyPropertyValues通过TypeConverter对value进行值得转换,具体的调用栈如下 具体的转换代码如下 从源码可以看出当customTypeConverter为空是,将会使用BeanWrapper进行转换,

u012807459的专栏 3188

SAP ABAP BADI_FINS_ACDOC_POSTING_EVENTS 深度应用:KO88工单结算的凭证字段定制与财务数据增强

本文深入探讨了SAP ABAP中BADI_FINS_ACDOC_POSTING_EVENTS在KO88工单结算中的应用,详细解析了如何通过BADI实现财务凭证字段的定制与数据增强。文章提供了从结构扩展到BADI方法实现的完整步骤,包括性能优化建议和实际应用中的测试验证流程,帮助开发人员高效解决企业个性化财务需求。

weixin_26869081的博客 389

SpringIOC源码阅读笔记(1)

刚看完springMVC的源码,感觉spring的容器源码还是掌握不到位,所以打算写一点笔记再理一遍思路。 一.Resource spring给资源提供了封装,根据不同的资源类型有不同的实现类,首先先看下UML图: 1.org.springframework.core.io.InputStreamSource 顶层接口,其中就定义了一个方法获取输入流: InputStream getInputStream() throws IOException 2.org.springframework.core.io

jacobbbbbbbb的博客 304

无人机通信安全渗透测试:从信号拦截到GPS欺骗的完整攻防框架

在物联网和智能设备普及的背景下,无线通信安全成为关键基础设施防护的核心环节。其原理在于,通过软件定义无线电等设备对空中的射频信号进行捕获、分析与模拟,从而评估通信协议在加密、认证和防重放等方面的脆弱性。这项技术的价值在于,它能主动发现并修复系统设计缺陷,避免因信号被拦截或欺骗导致设备被劫持、数据泄露等重大安全事件。其应用场景广泛,涵盖消费电子、工业控制及关键基础设施等领域。本文聚焦于无人机这一典型移动物联网终端,深入探讨如何构建一套针对其通信链路的渗透测试方法论,其中涉及信号拦截、协议逆向等关键技术,旨在为

weixin_34128237的博客 391

【抖音】a_bogus参数逆向分析

点击——展开xxx条回复﹀就会出现。可以看到这个栈是有请求相关的数据的。所以就是在bdms.js里面生成的。

qq_44990881的博客 3000

如何有效的阅读JDK源码

阅读Java源码的前提条件: 1、技术基础 在阅读源码之前,我们要有一定程度的技术基础的支持。 假如你从来都没有学过Java,也没有其它编程语言的基础,上来就啃《Core Java》,那样是很难有收获的,尤其是《深入Java虚拟机》这类书,或许别人觉得好,但是未必适合现在的你。 比如设计模式,许多Java源码当中都会涉及到。再比如阅读Spring源码的时候...

dl185249965的博客 243

病理WSI配准库valis教程

病理WSI配准库valis教程

azrealq的博客 2598

Spring源码阅读 -- > SpringIOC初始化流程

Spring IOC容器初始化

xinyu 234

28.Anaconda安装jupyter notebook、jupyterlab及体验

手贱,不小心将Anaconda自带得jupyter给卸载了,没法子了查了好多资料都比较麻烦,所以自己摸索着重新安装,记录一下心得。说明:Anaconda没有加入环境变量,Anaconda官方建议不要将Anaconda加入环境变量,这就意味着他和python是可以共存的。

迷逝 5028

nvidia系列教程-AGX-Orin linux源码下载编译

NVIDIA AGX Orin 是一款高性能的嵌入式计算平台,广泛应用于人工智能、自动驾驶、机器人等领域。为 AGX Orin 编译定制的 Linux 内核,可以更好地适应特定应用需求,增强系统的灵活性。本文将详细介绍如何下载、配置和编译适用于 AGX Orin 的 Linux 内核源码。本文介绍了如何为 NVIDIA AGX Orin 平台下载、配置和编译定制的 Linux 内核源码。通过编译和部署定制内核,您可以更好地控制系统的行为,并根据特定应用需求进行优化。

flypig has a dream! 1283

SpringIOC源码阅读笔记(3)

上篇笔记写到解析element分为解析默认标签以及自定义标签,本文就先从默认标签开始。 public static final String IMPORT_ELEMENT = "import"; public static final String ALIAS_ATTRIBUTE = "alias"; //bean public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT; public stati

jacobbbbbbbb的博客 199

用Python爬取大连商品交易所期货实时行情:从入门到实战

python复制编辑# utils.py"豆粕": "M0","铁矿石": "I0","聚乙烯": "L0","玉米": "C0","聚丙烯": "PP0","棕榈油": "P0"本项目展示了:✅ 如何从新浪财经 API获取主力合约实时数据✅ 使用Python异步爬虫技术) 提升效率✅ 利用pandas和matplotlib进行结构化分析与可视化✅ 具备良好的扩展性,可对接金融、农业、能源等数据需求场景✅ 可作为期货量化策略数据源✅ 可嵌入自动化报告系统。

2201_76125261的博客 1247

【Spring】Spring ioc源码学习以及关于阅读源码方式的一些小笔记

spring源码阅读笔记

要继续努力的孤独的博客 390

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Spring学习笔记--SpringIOC源码(一)

Spring学习笔记–SpringIOC源码 再查看源码的过程中我们应该遵守定焦原则和宏观原则,抓主线,关注源码结构和业务流程,通过断点、反调、和经验来阅读源码以此来提高培养代码架构思维并深入的理解框架。 SpringIOC容器初始化主体流程 Spring IoC的容器体系 IoC容器是Spring的核⼼模块,是抽象了对象管理、依赖关系管理的框架解决⽅案。Spring 提供了很多的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器 必须遵从的⼀套原则,具体的容

qq_40977467的博客 349

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

公开,阿里甩出“源码阅读指南”,原来源码才是最经典的学习范例

但其实真要把源码这东西搞定你得到的东西远比你想象的要多!以上就是阿里SSM源码阅读指南的部分内容了,本着有好东西就拿出来与大家分享的原则,另外我还为大家准备了一份JDK源码速成笔记:且往下看。借着这个机会,今天要与大家分享是来自阿里的SSM源码阅读指南,理论+源码设计模式一应俱全,大家拿到之后就知道,差距不止一点点!方便扩展,为所欲为(Spring是一个框架,同时是一个生态,作为整个生态的基础支撑,最重要的是扩展性)为了不影响大家的阅读体验,就不把篇幅拉太长了,只能展示主要内容,需要面试技巧的朋友点。...

JHIII的博客 168

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

SpringIOC源码阅读笔记(4)

上文讲到parsePropertySubElement,分析完这个方法,接着在parseBeanDefinitionElement向下分析: public void parsePropertyElements(Element beanEle, BeanDefinition bd) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i

jacobbbbbbbb的博客 263

SpringIOC源码阅读笔记(6)

从本文开始进行bean的加载过程的解析。 同样的我们可以从一行代码开始:MyTestBean bean = (MyTestBean)bf.getBean(“myTestBean”); 首先进入AbstractBeanFactory: @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } 代码很长,可以了解获得Bean的主要流程

jacobbbbbbbb的博客 161

SpringIOC源码阅读笔记(2)

整个ioc的过程可以分为3个步骤: 1.资源定位,根据location找到对应的资源。 2.装载,将资源解析到对应的beanDefinition。 3.注册,将beanDefinition中的对象注册进容器。 给一个简单的例子,后面的分析也将从这个例子中展开 BeanFactory bf= new XmlBeanFactory(new ClassPathResource(“beanFactory.xml”)) classpathresource的定位就不细说了, //XmlBeanFactory的主要实现都

jacobbbbbbbb的博客 192

SpringIOC源码阅读笔记(8)

上文讲到了创建bean总共有4种方法,已经分析了2种,分别是supplier获取以及工厂方法获取,接下来讲第三种: protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) { return new ConstructorResolver(th

jacobbbbbbbb的博客 187

SpringIOC源码阅读笔记(7)

创建bean的实现在AbstractAutowireCapableBeanFactory,入口是: @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instanc

jacobbbbbbbb的博客 222

SpringIOC源码阅读笔记(5)

分析完默认标签的解析,接下来分析自定义标签的解析: 方法的入口是在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions方法中,转到parseCustomElement, @Nullable public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); } @Nullable public BeanDefiniti

jacobbbbbbbb的博客 148

SpringIOC源码阅读笔记(9)

bean的创建的最后一步是初始化bean: protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> {

jacobbbbbbbb的博客 133

SpringIOC源码阅读笔记(11)

5.注册BeanPostProcessor,注意是注册,调用在getbean方法中。 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } public static void registerBeanPostP

jacobbbbbbbb的博客 126

SpringIOC源码解读

图解SpringIOC创建Bean的全过程,看完自己手写IOC

激流丶的博客 3913

dubbo源码深度解析_springIOC源码深度解析

点击上方Java老铁,并选择设为星标优质文章和资料会及时送达以前没有意识到阅读优秀框架源码的重要性,直到我阅读完mybatis、spring IOC、AOP, springMVC的源码,从中学了不少底层的知识,比如java的反射内省,jdk动态代理,cglib动态代理,体会到源码中使用了各种设计模式,使得框架具有非常强大的扩展性,那个时候我才发现框架也是很美的。废话不多说,下面开始我...

weixin_39650994的博客 239
上一篇: SpringIOC源码阅读笔记(9)
下一篇: SpringIOC源码阅读笔记(11)
jacobbbbbbbb
博客等级 码龄7年 6粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值