spring源码-ioc(一)

615 阅读3分钟

不要问我阅读spring源码有什么用,问就是没有用,只是让我自己使用spring的过程中自信点!

相关文章

spring-相关文章

说明

1. 本文只对的是注解形式 AnnotationConfigApplicationContext
2. 一般公司在使用的springmvc项目都是xml形式的
3. springboot是使用的Annotation,但是我们不会讲springboot,等spring-ioc讲完了再去说springboot
4. 我们是做测试,不是针对正常项目启动的,也就是 new AnnotationConfigApplicationContext(MyConfig.class);
5. spring-ioc东西特别的多,所以虽然我看了挺久的源码了,但是我也是在学习的过程
6. 目前没有给spring-ioc做分几篇文章的规划,因为我感觉就算规划了也不是很准,有很多地方我自己也是卡住的状态
7. 学习spring要对java反射,动态代理有所了解

使用AnnotationConfigApplicationContext

先看段代码

public static void main(String[] args) {
        //创建spring beanFactory 这里面就是我们常说的 spring-ioc的初始化 spring的核心之一
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
	//这个getBena 重要,属于spring初始化的过程,创建bean的实例,上面的代码只是把beanDefinition(bean的描述)放入对应的容器(就是个map),这句代码才是实例化
	TestController tc = ac.getBean(TestController.class);
	tc.jsontest("帅哥", 13);
}

@Configuration
@ComponentScan(value= "com.kiss.mxb")
public class MyConfig {
    //这是个配置类,标记了扫描的包
}

部分源码

下面去看看new AnnotationConfigApplicationContext(MyConfig.class) 究竟做了什么东西

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        //调用无参构造器(本文的主要内容)
	this();
	//注册我们传进来的这个配置类
	register(annotatedClasses);
	//这个忒别特别的重要
	refresh();
}

无参构造器

public AnnotationConfigApplicationContext() {
    //这里,创建读取器,其实里面主要的就是先注册几个 beanDefinition
	this.reader = new AnnotatedBeanDefinitionReader(this);
	//咋一看是和包的扫描有关系,但是后面你会发现没用到,我也不知道还有别的用
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

读取器的构造方法

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	//赋值一个注册器,这个注册器的功能就是把 beanDefinition 放入map
	//这个注册器其实就是beanFactory 本身,你可以看下AnnotationConfigApplicationContext 的顶层接口有一个就是 BeanDefinitionRegistry
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	//这个里面就是上面提到的注册几个beanDefinition,方法的参数为注册器,说明这几个beanDefinition是spring自己定义的bean
	//还有就是 注册这个词,听上去高大上,其实就是把一写数据放入一些map的过程
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

只看我们这个文章需要的代码,其余代码省略

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
    //获取bean工厂
	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);
        //这里 本文的重点,,也是贯穿spring-ioc的重点
        //主要是想spring注册一个bean工厂的后置处理器
	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));
	}
      //这个是注册了一个bean的后置处理器,这个后置处理器还想是在依赖注入的时候使用的
	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));
	}

	................................................................................................
	return beanDefs;
}
private static BeanDefinitionHolder registerPostProcessor(
		BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	//注册的代码就是这句,今天不说了以后会讲
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}

至于什么是bean的后置处理器和bean工厂的后置处理器,我会单独的章节介绍其用法.

总结

  1. 重要就是说了下无参构造器中注册了几个spring内部的bean
  2. 其中ConfigurationClassPostProcessor 这个bean工厂的后置处理器特别的重要