AnnotationConfigApplicationContext(1)之初始化Scanner和Reader

薩科拉發表於2021-11-19

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註解的例項化

相關文章