SpringBoot原理(二)--自动装配

SpringBoot自动装配原理

1 在上一文提到的启动流程中prepareContext准备上下文环境中的load方法会加载启动类

	private int load(Class<?> source) {
		if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
			// Any GroovyLoaders added in beans{} DSL can contribute beans here
			GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
			load(loader);
		}
		/**
		会判断传入的启动类是不是一个组件,有没有@Component注解,如果有则被AnnotateBeanDefinitionReader读取到,注册到beanDefinitionMap中,注册代码和spring的一样
		*/
		if (isComponent(source)) {
			this.annotatedReader.register(source);
			return 1;
		}
		return 0;
	}

2 在refreshContext()中调用refresh()方法,自动装配在invokeBeanFactoryPostProcessors()方法中实现,核心代码是里面的PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
由于这个方法代码较多,下面粘贴这个方法中的关键代码

/**
这行代码返回的类名是internalConfigurationAnnotationProcessor
 根据BeanDefinitionRegistryPostProcessor.class这个类从beanFactory中找到的
通过这个名字可以在AnnotationConfigUtils中识别到ConfigurationClassPostProcessor这个类,
自动装配的核心逻辑就是在这个类中。
ConfigurationClassPostProcessor这个类在上一篇文章ioc原理的时候有讲到,这里不再累述
*/
			String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			//
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //把ConfigurationClassPostProcessor放入到currentRegistryProcessors
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
					
				}
			}
			/**
			执行的核心方法是
			postProcessor.postProcessBeanDefinitionRegistry(registry)
			内的processConfigBeanDefinitions(registry);
			*/
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

2.1 processConfigBeanDefinitions(registry)方法中的解析方法parser.parse(candidates)
最终会调到sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
进行具体解析操作

/**
大体流程:
会解析到@ComponentScan,这里可以识别到我们自己定义的bean,
然后解析@Import,这里会根据启动类进行递归扫描@Import,会识别到两个@import,
然后取出里面的两个类AutoConfigurationImportSelector
和AutoConfigurationPackages.Registrar放入到一个set中进行处理。
在this.deferredImportSelectorHandler.process()会对这两个类进行处理,
调用类的getCandidateConfigurations方法,	
 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
getSpringFactoriesLoaderFactoryClass()方法得到EnableAutoConfiguration.class;
根据EnableAutoConfiguration.class这个类执行SpringFactoriesLoader.loadFactoryNames
加载spring.factories中根据EnableAutoConfiguration这个类获取对应的value值
得到全部自动装配的类,然后过滤掉一部分,
把需要的类封装成beanDefinition放入到beanDefinitionMap中
*/
	protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {
        //.........

		// Process any @PropertySource annotations
        //.........

		// Process any @ComponentScan annotations
        //.........

		// Process any @Import annotations
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		//.........


		// Process individual @Bean methods
		//.........


		// Process default methods on interfaces
		//.........
	

		// Process superclass, if any
		//.........

		// No superclass -> processing is complete
		return null;
	}

2.2 processImports(configClass, sourceClass, getImports(sourceClass), filter, true)方法会执行collectImports递归寻找@Import注解

	private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
			throws IOException {

		if (visited.add(sourceClass)) {
			for (SourceClass annotation : sourceClass.getAnnotations()) {
				String annName = annotation.getMetadata().getClassName();
				if (!annName.equals(Import.class.getName())) {
					collectImports(annotation, imports, visited);
				}
			}
			imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
		}
	}

2.3 解析注解完成之后parse方法会继续执行
this.deferredImportSelectorHandler.process();
处理@import取出里面的两个类,
处理AutoConfigurationImportSelector时会执行到核心方法getCandidateConfigurations

/**
getSpringFactoriesLoaderFactoryClass()方法得到EnableAutoConfiguration.class;
根据EnableAutoConfiguration.class这个类执行SpringFactoriesLoader.loadFactoryNames
加载spring.factories中根据EnableAutoConfiguration这个类获取对应的value值
*/
	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

2.4 parse方法结束后调用this.reader.loadBeanDefinitions(configClasses);会将所有需要注入的类,放入beanDefinitionMap中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值