AnnotationConfigApplicationContext(1)之初始化Scanner和Reader

AnnotationConfigApplicationContext(1)初始化Scanner和Reader

 

我们以AnnotationConfigApplicationContext为起点来探究Spring的启动过程

首先映入眼帘的就是AnnotationConfigApplicationContext的构造方法,而我们今天只来探讨this();

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//this()方法这里就创建了一个Bean工厂和Reader和Scanner
    this();
    register(componentClasses);
    refresh();
}

  

public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
   // 生成并注册5个BeanDefinition
   // 1.ConfigurationClassPostProcessor
   // 2.AutowiredAnnotationBeanPostProcessor
   // 3.CommonAnnotationBeanPostProcessor
   // 4.EventListenerMethodProcessor
   // 5.DefaultEventListenerFactory
   this.reader = new AnnotatedBeanDefinitionReader(this);
   createAnnotatedBeanDefReader.end();
   // 注册默认的includeFilter
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

 

AnnotationConfigApplicationContext首先会生成Reader和Scanner,但在这之前,BeanFactory其实已经实例化完成了

因为AnnotationConfigApplicationContext是GenericApplicationContext的子类,父类的构造器要优先于子类构造器执行,所以在执行AnnotationConfigApplicationContext类的无参构造时,会先执行GenericApplicationContext的无参构造:

public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
}

 

一、AnnotatedBeanDefinitionReader

Spring在实例化AnnotatedBeanDefinitionReader做了很多,最主要的就是将内部的后置处理器注册到Spring中

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;
       //ConditionEvaluator对象封装了spring容器的信息
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    /**
     * 将所有相关的后置处理器注册到这个registry中
     */
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

 

  将spring相关信息记录到conditionEvaluator对象后,spring开始注册相关后置处理器

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
    //将刚刚开始第一次new得bean工厂获得,
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
       //加载组件,其中包括AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
       //AnnotationAwareOrderComparator可以对实现PriorityOrdered、Ordered以及被@Order注解修饰的类进行统一的排序
       if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
        beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
           //AutowireCandidateResolver 用来判断一个给定的 bean 是否可以注入,最主要的方法是 isAutowireCandidate
       if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }
    //BeanDefinitionHolder中有beanDefinition,beanName,alias
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
       RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
       def.setSource(source);  //null
       /**
        * registerPostProcessor方法:
        * 将beanName和BeanDefinition按Key—value键值对得方式放在BeanDefinitionMap中
        * 将BeanName放在BeanDefinitionNames列表中,
        * 将BeanName和BeanDefinition封装在BeanDefinitionHolder中,
        * 将封装好得BeanDefinitionHolder放在BeanDefs列表中。
        * 这里其实就是注册内部的后置处理器
        */
       beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
        //AutowiredAnnotationBeanPostProcessor
    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.
    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));
    }
        //EventListenerMethodProcessor
    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));
    }inter
        //DefaultEventListenerFactory
    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;
}

 

  • EventListenerMethodProcessor和DefaultEventListenerFactory负责处理@EvenListen注解
  • ConfigurationClassPostProcessor会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
  • CommonAnnotationBeanPostProcessor负责解析@Resource、@WebServiceRef、@EJB三个注解。这三个注解都是定义在javax.*包下的注解,属于java中的注解。
  • AutowiredAnnotationBeanPostProcessor用于解析@Autowired

 

 

二、ClassPathBeanDefinitionScanner

 

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

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;
    if (useDefaultFilters) {
    //添加includeFilters
    //注册一个@Component注解对应的Filter
        registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}

 

 

 

  在开篇的时候我们提到了Scanner的用法,其中就提及到了includeFilters

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(factory);
//得到该包下类的个数
// int scan = classPathBeanDefinitionScanner.scan("com.beans");
// System.out.println(scan);//6
//扫描没有加@Componment注解的类,并注册到容器中,未通过注解或其他方式定义Bean的类也不会添加到容器中
//classPathBeanDefinitionScanner.addExcludeFilter(new AnnotationTypeFilter(Component.class));
//扫描加了@Componment注解的类,并注册到容器中
classPathBeanDefinitionScanner.addIncludeFilter(new AnnotationTypeFilter(Component.class));
//获取bean
Object bean = factory.getBean(BeanTest.class);
System.out.println(bean);//com.beans.BeanTest@5ccddd20

 

  Spring会默认向includeFilters添加了@Componment注解

protected void registerDefaultFilters() {
  this.includeFilters.add(new AnnotationTypeFilter(Component.class));
  ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
  try {
    this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
    logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
  }catch (ClassNotFoundException ex) {
    // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
  }
  try {
    this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
    logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
  }catch (ClassNotFoundException ex) {
    // JSR-330 API not available - simply skip.
  }
}

 

  到这里Spring就完成了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner的初始化和实例化

posted @ 2021-11-19 18:39  萨科拉  阅读(210)  评论(0编辑  收藏  举报