spring-ioc(一)

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

相关文章

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

先看段代码json

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) 究竟作了什么东西springboot

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

无参构造器mvc

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

读取器的构造方法post

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工厂的后置处理器特别的重要
相关文章
相关标签/搜索