spring源码解析【一】

spring源码解析

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
第一章 spring源码解析【一】spring整体流程


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

本文主要讲述spring整体的流程,细节将在该系列后续文章讲述。


提示:以下是本篇文章正文内容,下面案例可供参考

一、spring是什么?

spring其实就是一个开源应用框架,主要用来降低应用开发的复杂度。它可以集成其他框架,如Spring MVC、Hibernate、MyBatis等。是一个轻量级的Ioc和aop的容器框架。

二、整体流程

1.容器的创建

我们经常使用的容器创建有两种:ClassPathXmlApplicationContext和AnnotationConfigApplicationContext。ClassPathXmlApplicationContext是根据类加载路径的配置文件创建容器的,AnnotationConfigApplicationContext是根据注解创建容器的。首先我们看下ClassPathXmlApplicationContext的依赖图。
在这里插入图片描述

1.1ClassPathXmlApplicationContext创建容器的过程:

1.创建一个ClassPathXmlApplicationContext实例,参数选择类加载路径下配置文件。
在这里插入图片描述
2.在resources下创建配置文件spring_config.xml,里面使用bean标签注册bean。
在这里插入图片描述
3.使用容器的getBean()方法获取bean对象。

1.2ClassPathXmlApplicationContext源码解析

1.根据构造容器创建ClassPathXmlApplicationContext实例。
2.走到核心方法refresh()。该方法是阅读源码最好的入口,它能够帮助Spring完成beanFactory的创建和记载、bean的加载、以及后置处理器的注册等功能。这个方法包括了整个Spring的执行流程和bean的完整生命周期。refresh源码如下:

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 初始化前的准备工作,主要是一些系统属性、环境变量的校验,比如Spring启动需要某些环境变量,可以在这个地方进行设置和校验
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 获取bean工厂,ConfigurableListableBeanFactory是默认的容器,在这一步会完成工厂的创建以及beanDefinition的读取
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 进入prepareBeanFactory前spring以及完成了对配置的解析,Spring的拓展从这里开始
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 留给子类覆盖做拓展,这里一般不做任何处理
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// 调用所有的BeanFactoryPostProcessors,将结果存入参数beanFactory中
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 注册BeanPostProcessors,这里只是注册,真正的调用是在doGetBean中
			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.
			// 注册监听器
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 初始化剩下的单例bean,在这里才开始真正的对bean进行实例化和初始化
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 完成刷新,通知生命周期处理器刷新过程。
			finishRefresh();
		}
	}
}

1.这里挑些主要的逻辑说说,首先是obtainFreshBeanFactory方法,这方法完成bean工厂的创建,beanDefinition的读取,所以读取spring_config.xml文件就在这个方法里。主要的代码是在refreshBeanFactory中,在refreshBeanFactory方法中Spring会new一个DefaultListableBeanFactory 对象,DefaultListableBeanFactory 是Spring中默认的BeanFactory,接着对这个beanFactory进行定制化处理,调用XmlBeanDefinition的loadBeanDefinitions方法从xml文件中加载所有的beanDefinition并加载到这个DefaultListableBeanFactory 中。而这个this.beanFactory = beanFactory则是将该DefaultListableBeanFactory 设置为全局变量,变成整个Spring容器默认的beanFactory。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.prepareBeanFactory方法。

   protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	// 设置SPEL表达式解析器,用来支持Spring的SPEL表达式
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

	// 添加属性编辑注册器。例如一个字符串类型的地址需要转换为一个Address对象,可以使用该功能.
	// 可参考示例:spring-source-study模块下的com.wb.spring.propertyeditor包下的示例程序
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// 添加bean的后置处理器。此处添加的是Spring自己的后置处理器,用来回调bean所实现的aware接口中的方法.
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

	// 下面的ignoreDependencyInterface是用来设置bean工厂中需要忽略的接口
	// 可以通过实现EnvironmentAware接口来获取到当前的环境信息Environment。
	/**
	 * 如果将EnvironmentAware接口添加到ignoreDependencyInterface中,则在使用的地方通过@Autowired将会无法正常注入
	 *   而是需要通过setEnvironment方法进行注入,下面的其他接口都类似.
	 */
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	// 可以通过实现EmbeddedValueResolverAware接口来获取String类型值的解析器
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	// 资源加载器,例如使用:@Autowired ResourceLoaderAware aware; 将不会被注入
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	// 事件发布器
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	// 消息资源
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	// 应用的上下文信息
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// 注册一些可以自动装配的接口。 当类型为dependencyType时, 注入autowiredValue。为了解决一个类型有多个子类实现时,优先注入那个子类实现的问题。
	// 例如下面第一个,当注入类型为BeanFactory时,注入的值为beanFactory,默认为DefaultListableBeanFactory
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	// 当注入类型为ResourceLoader时,注入的值为ApplicationContext
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	// 当注入类型为ApplicationEventPublisher时,注入的值为ApplicationContext
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	// 当注入的类型为ApplicationContext时,注入的值为ApplicationContext.
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// 增加一个bean的后置处理器,ApplicationListenerDetector
	// Register early post-processor for detecting inner beans as ApplicationListeners.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	// 如果bean工厂中存在着名称为loadTimeWeaver的bean定义,则给bean工厂中加入LoaderTimeWeaverAwareProcessor后置处理器
	// 补充:1、增加对AspectJ的支持,在Java中织入分为3种:(1) 编译期织入; (2) 类加载期织入; (3) 运行期织入。编译期织入指的是在java编译期,
	//         采用特殊的编译器,将切面织入到java类中;类加载期织入则指的是通过特殊的类加载器,在字节码加载到JVM时,织入切面;运行期织入则是
	//         通过采用cglib或者jdk进行切面的织入。
	//      2、aspectJ中提供了两种方式:
	//         (1) 通过特殊编译器,在编译期,将aspectJ语言编写的切面类织入到java类中;
	//         (2) 类加载期织入,就是通过下面的LoadTimeWeaving
	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()));
	}

	// 给容器中注册一些与运行环境相关的单实例Bean
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		// beanName: environment,直接将new出来的Spring内部对象放入到Spring的单实例缓存池中.
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}

	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		// beanName: systemProperties   方法:System.getProperties();
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}

	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		// beanName: systemEnvironment,   方法:System.getEnv();
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

3.invokeBeanFactoryPostProcessors方法
在这个方法中主要做三件事:
(1)加载入参的beanFactoryPostProcessors
优先加载BeanDefinitionRegistryPostProcessor类型的,并且会直接调用一次registryProcessor.postProcessBeanDefinitionRegistry(registry)方法,然后分别将BeanDefinitionRegistryPostProcessor类型的和BeanFactoryPostProcessor放入不同类型的容器中。
(2)加载上下文的BeanDefinitionRegistryPostProcessor。
(3)加载上下文的BeanFactoryPostProcessor
和第二步顺序一样也是按照PriorityOrdered、Ordered、和其他的BeanFactoryPostProcessor的顺序加载。
4.finishBeanFactoryInitialization方法
这个方法也是重点,Spring就是在这里完成非懒加载的单例bean的加载的。其中bean的加载和初始化就是在preInstantiateSingletons中,如果getBean的结果为null,Spring就会通过beanName在工厂中拿到对应的beaDefinition,开始加载bean。

	 public void preInstantiateSingletons() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		// 获取所有的beanName
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 遍历BeanName
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 如果BeanDefinition符合单例、非懒加载、非抽象的类,就开始加载bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					// 获取bean
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// FactoryBean是特殊的bean,需要特殊处理。FactoryBean是通过getObject方法获取真正的对象
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 获取bean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 触发所有bean的回调
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

1.3 AnnotationConfigApplicationContext创建容器过程

1.创建AnnotationConfigApplicationContext实例。
在这里插入图片描述
2.AppConfig配置类加扫描路径注解。
在这里插入图片描述
3.User类加注解变成bean对象。
在这里插入图片描述

1.4 AnnotationConfigApplicationContext源码解析

1.继承关系图
在这里插入图片描述
2.构造方法。
在这里插入图片描述
3.this方法中创建两个对象,一个reader,一个scanner。
scanner,主要是为了方便在创建完AnnotationConfigApplicationContext对象时手动进行scan。
reader是重点。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

这个方法注册了6个BeanDefinition,分别会处理不同的注解。这里最重要的是ConfigurationClassPostProcessor这个增强器,因为它会解析@ComponentScan注解,将扫描该注解下的所有@Component等注册注册bean定义。

在这里插入图片描述
重点:何时回调后置处理器解析beanDefination。
在refresh方法中的invokeBeanFactoryPostProcessors方法,然后调用postProcessBeanDefinitionRegistry方法,紧接着调用processConfigBeanDefinitions,然后重点关注parser.parse方法,然后是processConfigurationClass,然后是doProcessConfigurationClass,然后是this.componentScanParser.parse,然后是scanner.doScan,该方法就是扫描@ComponentScan指定包下面的注解。
在这里插入图片描述
在这里插入图片描述
这里就是扫描后生成的BeanDefinitions。
在这里插入图片描述
在这里插入图片描述

3.refresh方法解析同上。

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值