SpringBoot之Bean解析

Spring IOC思想

官方文档

This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1]principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
本章介绍了控制反转(IoC)[1]原理的Spring框架实现。IoC也称为依赖项注入(DI)。它是一个对象定义其依赖项的过程,也就是说,对象只通过构造函数参数、工厂方法的参数或对象实例构造或从工厂方法返回后在对象实例上设置的属性来定义它们所使用的其他对象。然后容器在创建bean时注入这些依赖项。这个过程基本上与bean本身相反,因此称为控制反转(IoC), bean本身通过使用类的直接构造或服务定位器模式等机制来控制其依赖项的实例化或位置。
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。否则,bean只是应用程序中的众多对象之一。bean及其之间的依赖关系反映在容器使用的配置元数据中。

IOC全称为“Inversion of Control”,即控制反转,不是一种技术,而是一种设计思想。在这种设计思想中,你设计好的对象交给容器管理,而不是在应用程序内部对对象进行管理。控制的含义是IOC容器控制了对象(也可以包括文件及其他外部资源);而反转的含义是IOC容器负责创建及注入依赖的对象,但在传统的应用程序中,我们需要在对象内部去创建(new)依赖的对象,这叫“正”,在这样的情况下,对象之间的耦合度就非常高。IOC更像是一种中介,帮助雇佣者和被雇佣者。
在这里插入图片描述

refresh()方法解析

在这里插入图片描述

  • prepareRefresh();
	protected void prepareRefresh() {
		// Switch to active.
		// 记录启动时间,
    	// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		//初始化属性,配置servletContext,servletConfig
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		//检验是否配置必备的属性,如果这个属性没有配置,则报错
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

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

1.容器状态的设置。
2.初始化属性的设置。
3.检查必备属性是否存在。

  • obtainFreshBeanFactory()
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

错误的分析
进入refreshBeanFactory()方法

	~~@Override
	/*protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		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);
		}
	}*/
	/**
	 * 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.
	 */~~ 

根据方法注释我们可以知道,这个方法主要是为上下文生命周期的下一阶段初始化一个新的bean工厂,如果之前已经存在bean工厂的话,则关闭在以前的初始化一个新的bean工厂,同时为其设置序列号ID。在customizeBeanFactory(beanFactory)中设置beanFactory是否允许bean定义的覆盖,和是否允许循环引用。refreshBeanFactory就是进行Bean的发现,读取和注册实现。
分析到这里我发现我跟错代码了…
AbstractApplicationContext是一个抽象类,它有两个实现类实现了refreshBeanFactory()方法
在这里插入图片描述
我断点调试可以知道,进入的是GenericApplicationContext的refreshBeanFactory()方法,因为我们创建的ApplicationContext为AnnotationConfigServletWebServerApplicationContext
在这里插入图片描述
我们看一下AnnotationConfigServletWebServerApplicationContext的UML图
在这里插入图片描述AnnotationConfigServletWebServerApplicationContext继承ServletWebServerApplicationContext,而ServletWebServerApplicationContext继承GenericWebApplicationContext,因为子类没有重写refreshBeanFactory(),所以我们这里调用的是GenericWebApplicationContext的refreshBeanFactory()方法。
进入refreshBeanFactory()方法

	@Override
	protected final void refreshBeanFactory() throws IllegalStateException {
		if (!this.refreshed.compareAndSet(false, true)) {
			throw new IllegalStateException(
					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
		this.beanFactory.setSerializationId(getId());
	}

标志refreshed,表面BeanFactory已经更新,设置BeanFactory的序列化ID。
总的来说,obtainFreshBeanFactory设置beanFactory,并返回。

  • prepareBeanFactory();
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置 BeanFactory 的类加载器,这里设置为当前 ApplicationContext 的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 设置表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    // 添加Aware后置处理器,实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    /**
     * 下面几行的意思是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,Spring 会通过其他方式来处理这些依赖
     */
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    /**
    * 下面几行是为了解决特殊的依赖,如果有 bean 依赖了以下几个(可以发现都是跟容器相关的接口),会注入这边相应的值,
    * 这是因为 Spring 容器里面不保存容器本身,所以容器相关的依赖要到 resolvableDependencies 里面找。上文有提到过,
    * ApplicationContext 继承了 ResourceLoader、ApplicationEventPublisher、MessageSource,所以对于这几个依赖,
    * 可以赋值为 this,注意 this 是一个 ApplicationContext。
    * 那这里怎么没看到为 MessageSource 赋值呢?那是因为 MessageSource 被注册成为了一个普通的 bean
    */
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);


    /**
     * 这也是个 BeanPostProcessor ,在 bean 实例化后,如果是 ApplicationListener 的子类,那么将其添加到 listener 列表中,
     * 可以理解成:注册监听器
     */
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }


    /**
     * 从下面几行代码我们可以知道,Spring 往往很 "智能" 就是因为它会帮我们默认注册一些有用的 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());
    }
}
  • postProcessBeanFactory();
	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.postProcessBeanFactory(beanFactory);
		if (this.basePackages != null && this.basePackages.length > 0) {
			this.scanner.scan(this.basePackages);
		}
		if (!this.annotatedClasses.isEmpty()) {
			this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
		}
	}

调用父类实现

	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		registerWebApplicationScopes();
	}

总的来说,首先是增加一个beanPostProcessor处理器,主要用于在bean初始化前后设置servlet相关配置,registerWebApplicationScopes()注册web应用的作用域和环境配置信息。这里需要注意的是basePackages 和this.annotatedClasses.isEmpty()的条件都不满足
在这里插入图片描述
所以不会通过scanner, reader来注册beanDefinition。
总的来说,postProcessBeanFactory用于子类重写以在BeanFactory完成创建后,用于进一步的设置。

  • invokeBeanFactoryPostProcessors();
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()));
		}
	}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扫描二维码关注公众号,回复: 10640214 查看本文章
  • 首先通过getBeanFactoryPostProcessors查找手动配置的beanFactory后置处理器。(在前面分析的Initializer和listener中增加)

  • 判断其是否实现BeanDefinitionRegistryPostProcessor接口,如果是则先执行postProcessBeanDefinitionRegistry方法,并区分暂存到两个集合当中。BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。

  • 通过beanFactory的getBeanNamesForType方法来查找容器中BeanDefinitionRegistryPostProcessor的实现,然后按优先级及排序,非排序等分别执行。

  • 把BeanDefinitionRegistryPostProcessor接口的方法都执行完成后,再分别执行其BeanFactoryPostProcessor接口的方法(这里包括手动配置及容器中查找的),并记录名字到集合。

  • 把BeanDefinitionRegistryPostProcessor接口的方法都执行完成后,再分别执行其BeanFactoryPostProcessor接口的方法(这里包括手动配置及容器中查找的),并记录名字到集合。
    总的来说,简单描述下,就是先查找BeanDefinitionRegistryPostProcessor接口实现并执行postProcessBeanDefinitionRegistry方法实现向容器中添加bean的定义,然后再查找执行BeanFactoryPostProcessor接口的实现,并执行postProcessBeanFactory方法,向容器中bean的定义添加属性。

  • registerBeanPostProcessors(beanFactory);

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
                // 查找BeanPostProcessor实现的名称
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 添加BeanPostProcessorChecker,用于打印日志提示在BeanPostProcessor实例化期间新建bean,不能被全部的BeanPostProcessor实例处理
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 按优先级,排序,非排序等分类调用.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		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);
			}
		}

		// 先是优先级高的
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 再是实现排序的
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			// 记录内部处理
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 然后是普通的
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			// 记录内部处理
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 最后是MergedBeanDefinitionPostProcessor的实现
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 最最后增加一个关于ApplicationListener的探测类
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

总的来说就是找到BeanPostProcessor的实现,排序后又注册进容器中。

  • initMessageSource();
protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		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());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

初始化国际化相关的属性

  • initApplicationEventMulticaster();
    初始化事件广播器注册到容器当中。
  • onRefresh();
    该方法主要由AbstractApplicationContext子类来扩展实现,因为我们的web服务,所以由于ServletWebServerApplicationContext实现,主要是实例化web服务,比如ServletContext上下文配置,tomcat初始化配置等。
  • registerListeners
    添加容器内的监听器到事件广播器当中,然后派发早期没有处理的事件。
  • finishBeanFactoryInitialization(beanFactory);
    初始化单例的bean。这里不做详细的分析,后面会另开一章分析。
  • finishRefresh();
    初始化生命周期处理器,完成刷新工作,清除缓存;注册LifecycleProcessor的实现DefaultLifecycleProcessor并调用onRefresh方法;发布刷新事件;启动web服务等。
  • resetCommonCaches();
    处理上述方法产生的缓存的数据
    参考 :1
    2
    3
    4
发布了6 篇原创文章 · 获赞 0 · 访问量 273

猜你喜欢

转载自blog.csdn.net/weixin_43960292/article/details/105385441