SpringBoot源码(九): createApplicationContext

介绍

前面一章介绍了启动流程中的打印banner,接下来继续根据springBoot启动的源码分析,createApplicationContext方法。ApplicationContext是spring容器的核心,其实一般我们所说的spring容器,一般也可以说是ApplicationContext,具体点就是ApplicationContext里的DefaultListableBeanFactory,后面在bean的创建时候会详细介绍的,现在就先了解下ApplicationContext的创建,以及在创建时候做的一些初始化工作。

源码

springBoot启动流程创建ApplicationContext的源码

	public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.boot."
			+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

	public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
			+ "annotation.AnnotationConfigApplicationContext";


	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
                // 根据webApplicationType类型加载class文件
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default:
					contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
				}
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, "
								+ "please specify an ApplicationContextClass",
						ex);
			}
		}
        // 创建无参的对象
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}

从源码中看到根据webApplicationType来加载class文件,对于webApplicationType第一章就说过了,在springApplication启动初始化时候,会根据时候存在的class文件来判断类型。一般我们都是web服务,所以启动都是servlet类型的。

也就是我们会创建org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext。

接下来看AnnotationConfigServletWebServerApplicationContext的无参数构造方法。

public class AnnotationConfigServletWebServerApplicationContext
		extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {

	private final AnnotatedBeanDefinitionReader reader;

	private final ClassPathBeanDefinitionScanner scanner;

	private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();

	private String[] basePackages;


	public AnnotationConfigServletWebServerApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

    /**
    * 省略其他代码
    */

}

在这里我们先不讨论Bean以及BeanDefinition,暂时只需要知道这边创建了一个扫描注解的和读取以及注册bean的类。主要看下reader的创建。

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}

	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<>(4);

        // 注册一个对于Bean的解析类到spring的BeanDefinitionMap中
		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));
		}

        // 注册一个对于@AutoWired的解析类
		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));
		}
        
        // 注册一个对必要配置验证的类
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

        // 注册一个对@Resource解析的类
		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));
		}
        
        // 注册解析@EventListener的类
		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;
	}

这里是对于几个类加到spring容器中,具体干嘛后面会用到这里只是先了解下,有这么几个类。

  • ConfigurationClassPostProcessor:对于应用程序下所有Bean解析并且注入到容器中,比如@Component以及被@Component注解的@Service,@Controller,@Repository等,还有@Bean,@Import注解等加到bean定义的map中去。
  • AutowiredAnnotationBeanPostProcessor:对于@Autowired注解修饰的字段或者方法解析,加入到bean定义的map中
  • RequiredAnnotationBeanPostProcessor:对于必要属性验证
  • CommonAnnotationBeanPostProcessor:对于@Resource注解修饰的字段或者方法解析,加入到spring容器中,并且解析@PostConstruct,@PreDestory注解。这两个注解分别用作Bean初始化和销毁时候用的。后面说到源码时候再说。
  • EventListenerMethodProcessor,DefaultEventListenerFactory:这两个类主要用于spring中事件的发布。一般我们在使用spring事件的时候,都是实现ApplicationListener,具体源码逻辑第二章说过了,可以去看下。但是后来版本中Spring又加了一个@EventListener的注解,这个注解可以放到方法上去。这样就简化了对于事件的使用,就不需要再去实现ApplicationListener了,事件多的时候比较优雅,不然同一个事件,不同的处理方式,就要实现很多的ApplicationListener类了。

这里对于这几个类先需要有个印象,因为后面会用到,在讲到源码的时候会详细讲解。这里面涉及到很多,比如ApplicationContext,还有BeanFactory。这些都会在创建Bean的时候说到。

总结

这节主要介绍了createApplicationContext以及在构造时候向spring容器中加入的几个类。对于具体干嘛用的,在后面会一点一点说到,现在只需要简单了解下这几个类就行了。对于提到的加入spring容器,我觉得暂时暂时可以理解成ApplicationContext里的DefaultListableBeanFactory(其实是加到里面的一个map里)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值