springboot源码走读之三----context生成【 createApplicationContext】

前面的话

前面两篇文章主要是走读了springboot启动时的准备阶段,本文正式进入重点的阶段。即spring context的生成。即如下代码:

//生成spring的context
    context = createApplicationContext();
// 异常上报
    exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);
//准备spring context
    prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//组装spring context,这一步是重点。主要是spring的机制
    refreshContext(context);

下面来分别走读每行代码。

createApplicationContext

createApplicationContext的代码如下:

protected ConfigurableApplicationContext createApplicationContext() {
        Class contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch (this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName(DEFAULT_SERVLET_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);
    }

根据不同的webType初始化不同的context。如果是servlet,则通过反射,初始化org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext,如果是reactive类型,则初始化org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext,如果都不是上面的类型,则初始化org.springframework.context.annotation.AnnotationConfigApplicationContext.
本文主要走读servlet类型。下面主要看AnnotationConfigServletWebServerApplicationContext的类图。

AnnotationConfigServletWebServerApplicationContext.png

这里看下初始化AnnotationConfigServletWebServerApplicationContext干了哪些事情。
由于该类继承了GenericApplicationContextGenericApplicationContext中的构造方法里初始化了beanfactory。

    /**
     * Create a new GenericApplicationContext.
     * @see #registerBeanDefinition
     * @see #refresh
     */
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }

这里直接new出一个DefaultListableBeanFactory出来。
AnnotationConfigServletWebServerApplicationContext的无参构造方法里做了哪些事情呢?

    public AnnotationConfigServletWebServerApplicationContext() {
              //注解相关的处理
        this.reader = new AnnotatedBeanDefinitionReader(this);
              //scan相关处理
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

初始化reader和scanner。具体做的事情是什么呢?
new AnnotatedBeanDefinitionReader(this);的代码如下:

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);
    }

代码中this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);是注册Conditional注解家族的处理类。Conditional注解主要作用是,注册满足条件的bean,Conditional注解家族有如下成员:

Conditional注解成员

当然,我们也可以自定义条件,只需要实现Condition接口。定义如下:

public interface Condition {

    /**
     * Determine if the condition matches.
     * @param context the condition context
     * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
     * or {@link org.springframework.core.type.MethodMetadata method} being checked
     * @return {@code true} if the condition matches and the component can be registered,
     * or {@code false} to veto the annotated component's registration
     */
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

然后在使用的时候,在类或者方法上使用@Conditional(yourconditon.class)

代码中AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);主要是实例化spring相关注解的bean。
代码如下

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

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                              //@Order的处理bean
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                                //@Lazy,@Qualifier的处理bean
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set beanDefs = new LinkedHashSet<>(8);

              //@Configuration 注解的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));
        }
                //@Autowired 和@Value注解的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));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
                //java 自有注解的处理,如@Resource,@PostConstruct,@PreDestroy等
        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.
                // JPA相关注解的处理
        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;
    }

接下来,走读this.scanner = new ClassPathBeanDefinitionScanner(this);
代码如下:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
            Environment environment, @Nullable ResourceLoader resourceLoader) {

        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;

        if (useDefaultFilters) {
            registerDefaultFilters();
        }
        setEnvironment(environment);
        setResourceLoader(resourceLoader);
    }

这段代码主要是注册扫描的默认过滤规则,默认规则扫描@Component ,@Repository,@Service,@Controller等及JAVAEE6的@ManagedBean和JSR-330的@Named。
至此,context的初始化算是告一段落了,总结下来,在初始化context时,做了哪些事情呢?
1、通过webType,获取不同的context class,这里以servlet为例走读。通过反射初始化AnnotationConfigServletWebServerApplicationContext
2、在context例初始化beanFactory。new一个DefaultListableBeanFactory。
3、注册bean的处理类。如:conditional,@order,@lazy,@autowared等注解的处理。
4、注册扫描规则等。

你可能感兴趣的:(springboot源码走读之三----context生成【 createApplicationContext】)