spring源码解析(三) applicationContext启动过程

applicationContext启动过程  

首先去准备容器,也就是 new一个applicationcontext,Config.class为@ComponentScan注解标记的类。

AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(Config.class);

调用它自己的构造方法。

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   // 1. 创建BeanFactory
   // 2. 生成AnnotatedBeanDefinitionReader
   // 3. 生成ClassPathBeanDefinitionScanner
   this();

   // 利用reader把componentClasses注册为一个BeanDefinition
   register(componentClasses);

   // 调用AbstractApplicationContext的refresh()方法,模板模式,会启动ApplicationContext
   // 为什么叫refresh,而不叫start?
   refresh();
}

看一下this()方法

因为AnnotationConfigApplicationContext对象继承了GenericApplicationContext对象,所以要先调用GenericApplicationContext的构造方法。

也就是创建了一个beanFactory对象。DefaultListableBeanFactory是beanFactory的最终实现类,功能及其强大。

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

调用完父类的构造方法以后,回到自己的构造方法中。

public AnnotationConfigApplicationContext() {
   // 在执行这个构造方法之前,会先执行父类的构造方法,会初始化一个beanFactory = new DefaultListableBeanFactory()

   // 生成并注册5个BeanDefinition
   // 1.ConfigurationClassPostProcessor
   // 2.AutowiredAnnotationBeanPostProcessor
   // 3.CommonAnnotationBeanPostProcessor
   // 4.EventListenerMethodProcessor
   // 5.DefaultEventListenerFactory
   this.reader = new AnnotatedBeanDefinitionReader(this);

   // 注册默认的includeFilter
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

这个方法主要是生成注册五个重要的BeanDefinition

1.ConfigurationClassPostProcessor 解析配置类(重点)BeanFactoryPostProcessor

2.AutowiredAnnotationBeanPostProcessor 用于@Autowired、@Value

3.CommonAnnotationBeanPostProcessor 用于@Resource

4.EventListenerMethodProcessor 用于@EventListener

5.DefaultEventListenerFactory 用于@EventListener

将这些重要的bean定义后,回到this.scanner = new ClassPathBeanDefinitionScanner(this);这个方法,添加@Component注解。这时已经将config.class的beanDefinition注册进去了。

然后接着到register(componentClasses);方法,通过reader将含有@Component注解的类转为beanDefinition。

然后调用refresh();方法先看一下源码,

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 刷新BeanFactory,得到一个空的BeanFactory
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 准备BeanFactory
      // 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
      // 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
      // 3. 记录ignoreDependencyInterface
      // 4. 记录ResolvableDependency
      // 5. 添加三个单例Bean
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 子类可以对BeanFactory进行进一步初始化
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         // BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
         // 默认情况下:
         // 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
         // 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
         // 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
         // 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         // 初始化MessageSource,如果配置了一个名字叫做“messageSource”的BeanDefinition
         // 就会把这个Bean创建出来,并赋值给ApplicationContext的messageSource属性
         // 这样ApplicationContext就可以使用国际化的功能了
         initMessageSource();

         // Initialize event multicaster for this context.
         // 设置ApplicationContext的applicationEventMulticaster
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         // 执行子类的onRefresh方法
         onRefresh();

         // Check for listener beans and register them.
         // 注册Listener
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         // 完成beanFactory的初始化(实例化非懒加载的单例bean)
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         // 发布事件
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

看这一步obtainFreshBeanFactory(),点进去发现有两个实现类,

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

1.GenericApplicationContext

2.AbstractRefreshableApplicationContext

如果是GenericApplicationContext这个类去实现发现提示不能再次刷新报错。

而AbstractRefreshableApplicationContext则可以再次进行刷新。

相对于的AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能再次刷新的。

AnnotationConfigWebApplicationContext继承的是AbstractRefreshableWebApplicationContext,所以它是可以再次刷新的。

然后查看AbstractRefreshableApplicationContext的刷新逻辑,将bean和beanFactory等销毁再创建。

protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

如果手动添加了beanFactoryPostProcessor,那么需要刷新refresh一下,否则加载不进来。也算是体现了为什么要refresh了。

为什么手动添加就需要刷新一下了呢?

手写demo如下,创建ac时不能入参,否则就会直接调用refresh方法。这个ac容器还只支持刷新一次,所以只能这么写。

写法如下:

AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
applicationContext.register(Config.class);
applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
applicationContext.refresh();

首先创建一个无参的AnnotationConfigApplicationContext对象,执行无参构造器时不执行refresh()方法。然后我们需要手动添加进去配置类,但没有这个对象时是无法添加进去的,所以只能先得到这个对象后,去添加这个配置类,然后再执行refresh,这时才会将配置类注册进去。

让我们回到refresh方法,查看这个方法invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法,也就是刚才那个demo方法手动注册的。
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// BeanDefinitionRegistryPostProcessor是一个特殊的BeanFactoryPostProcessor,需要先执行postProcessBeanDefinitionRegistry方法
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;

					registryProcessor.postProcessBeanDefinitionRegistry(registry);

					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// 保存当前需要执行的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 首先,先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 判断这个类是否还实现了PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
			// 然后,先执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 最后,最后其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
			boolean reiterate = true;
			// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
			// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
			while (reiterate) {
				reiterate = false;
				// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法后,
			// 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 执行手动添加的非BeanDefinitionRegistryPostProcessor类型的Bean工厂后置处理器的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 如果beanFactory没有可以注册BeanDefinition的功能,则没有BeanDefinitionRegistryPostProcessor,则执行Bean工厂后置处理器的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 在默认情况下,上面的步骤中只有一个BeanDefinitionRegistryPostProcessor会执行,就是ConfigurationClassPostProcessor,因为它是Spring默认在添加进去的

		// BeanDefinitionRegistryPostProcessor是特殊的BeanFactoryPostProcessor,在上面的逻辑中都处理完了
		// 所以接下来就是处理普通的BeanFactoryPostProcessor
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		// 默认情况下会拿到两个,一个就是ConfigurationClassPostProcessor,一个就是EventListenerMethodProcessor

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 保存直接实现了BeanFactoryPostProcessor接口和PriorityOrdered接口的后置处理器
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口和Ordered接口的后置处理器
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口的后置处理器,不包括那些实现了排序接口的类
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 把所有BeanFactoryPostProcessor进行分类
		for (String ppName : postProcessorNames) {
			// 拿到的BeanFactoryPostProcessor包括了BeanDefinitionRegistryPostProcessor,所以要跳过
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		// 先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 再执行实现了Ordered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		// 最后执行普通的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 到此,所有的BeanFactoryPostProcessor都执行完了
		// 对于BeanFactoryPostProcessor我们可以这么理解:它是去完善BeanFactory的,比如向BeanFactory中去注册BeanDefinition
		// 就好比:BeanFactory是一张白纸,每个BeanFactoryPostProcessor都去这张白纸上去画上一笔,这个白纸就丰满了

		// 所以这段代码,虽然内容很多,但是在默认情况下,主要就是执行了ConfigurationClassPostProcessor
		// 1. 先执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,基本上就是去注册BeanDefinition
		// 2. 然后执行了ConfigurationClassPostProcessor的postProcessBeanFactory方法

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

总结一下:

先判断ApplicationContext手动添加的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。

然后就是判断实现了实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。

接着实现了Ordered接口的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册)。

最后将所有的BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry方法(bean定义的注册),将所有没执行过的执行一次。

(这么做的目的是分组执行beanDefinition的注册,按先后顺序。PriorityOrdered>Ordered>无

执行完postProcessBeanDefinitionRegistry后,再执行全部的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法。

对于BeanFactoryPostProcessor接口我们可以这么理解:它是去完善BeanFactory的,比如向BeanFactory中去注册BeanDefinition

就好比:BeanFactory是一张白纸,每个BeanFactoryPostProcessor都去这张白纸上去画上一笔,这个白纸就丰满了

在默认情况下,主要就是执行了ConfigurationClassPostProcessor

1.先执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,基本上就是去注册BeanDefinition

2. 然后执行了ConfigurationClassPostProcessor的postProcessBeanFactory方法。

ConfigurationClassPostProcessor

因为spring默认是执行ConfigurationClassPostProcessor这个bean,所以来详细分析一下里面的内容。

在调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry时,在processConfigBeanDefinitions方法里有这么一个方法

ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)

该方法的作用:检查BeanDefinition是不是配置类候选者,

那么什么样的BeanDefinition符合呢?

1. 存在@Configuration的就是配置类,或者

2. 存在@Component,@ComponentScan,@Import,@ImportResource,或者

3. 存在@Bean标注的方法

源码:

//存在@Configuration,并且proxyBeanMethods=true
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) 
static {
    //有这四个注解的话就作为候选者
   candidateIndicators.add(Component.class.getName());
   candidateIndicators.add(ComponentScan.class.getName());
   candidateIndicators.add(Import.class.getName());
   candidateIndicators.add(ImportResource.class.getName());
}
//是否有@Bean
return metadata.hasAnnotatedMethods(Bean.class.getName());

识别了以后做什么? ----开始解析配置类

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry-》processConfigBeanDefinitions-》 parse-》processConfigurationClass-》doProcessConfigurationClass

具体解析都在doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
      throws IOException {

   // 1. 如果配置bean上有@Component注解,递归去解析内部类上的注解
   if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
      // Recursively process any member (nested) classes first
      processMemberClasses(configClass, sourceClass);
   }

   // Process any @PropertySource annotations
   // 2. 解析@PropertySource注解
   for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
         sourceClass.getMetadata(), PropertySources.class,
         org.springframework.context.annotation.PropertySource.class)) {
      if (this.environment instanceof ConfigurableEnvironment) {
         processPropertySource(propertySource);
      }
      else {
         logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
               "]. Reason: Environment must implement ConfigurableEnvironment");
      }
   }

   // Process any @ComponentScan annotations
   // 3. 解析@ComponentScan注解,并进行扫描
   Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
         sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
   if (!componentScans.isEmpty() &&
         !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
      for (AnnotationAttributes componentScan : componentScans) {

         // The config class is annotated with @ComponentScan -> perform the scan immediately
         // 扫描得到BeanDefinition,解析@ComponentScan里的各种属性
         Set<BeanDefinitionHolder> scannedBeanDefinitions =
               this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

         // Check the set of scanned definitions for any further config classes and parse recursively if needed
         for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
            BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
            if (bdCand == null) {
               bdCand = holder.getBeanDefinition();
            }

            // 检查扫描所得到BeanDefinition是不是配置Bean,基本上都有@Component注解,所以都是配置类
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
               parse(bdCand.getBeanClassName(), holder.getBeanName());
            }
         }
      }
   }

   // Process any @Import annotations
   // 4. 解析@Import,getImports方法返回AppConfig.class上定义的Import注解中所导入的类的信息
   processImports(configClass, sourceClass, getImports(sourceClass), true);

   // Process any @ImportResource annotations
   // 5. 解析@ImportResource,得到导入进来的spring的xml配置文件,然后解析
   AnnotationAttributes importResource =
         AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
   if (importResource != null) {
      String[] resources = importResource.getStringArray("locations");
      Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
      for (String resource : resources) {
         String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);

         configClass.addImportedResource(resolvedResource, readerClass);
      }
   }

   // Process individual @Bean methods
   // 6. 解析配置类中的加了@Bean注解的方法
   Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
   for (MethodMetadata methodMetadata : beanMethods) {
      configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
   }

   // Process default methods on interfaces
   // 7. 如果配置类实现了某个接口,那么则解析该接口中的加了@Bean注解的默认方法
   processInterfaces(configClass, sourceClass);

   // Process superclass, if any
   // 8. 如果有父类,则返回父类给上层遍历进行处理
   if (sourceClass.getMetadata().hasSuperClass()) {
      String superclass = sourceClass.getMetadata().getSuperClassName();
      if (superclass != null && !superclass.startsWith("java") &&
            !this.knownSuperclasses.containsKey(superclass)) {
         this.knownSuperclasses.put(superclass, configClass);
         // Superclass found, return its annotation metadata and recurse
         return sourceClass.getSuperClass();
      }
   }

   // No superclass -> processing is complete
   return null;
}

解析顺序:@Component-》@PropertySource-》@ComponentScan-》@Import-》@ImportResource-》@Bean

再回到这个方法processConfigBeanDefinitions。此时我们已经通过parse方法将配置类都解析出来了。

parser.parse(candidates);
parser.validate();

Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
   this.reader = new ConfigurationClassBeanDefinitionReader(
         registry, this.sourceExtractor, this.resourceLoader, this.environment,
         this.importBeanNameGenerator, parser.getImportRegistry());
}

// 利用reader解析ConfigurationClass,同时注册BeanDefinition
this.reader.loadBeanDefinitions(configClasses);

比如我断点到这里有这么几个ConfigurationClass:

现在我们进入到reader对象的loadBeanDefinitions方法

loadBeanDefinitions-》loadBeanDefinitionsForConfigurationClass-》loadBeanDefinitionsForBeanMethod

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
   ConfigurationClass configClass = beanMethod.getConfigurationClass();
   MethodMetadata metadata = beanMethod.getMetadata();
   String methodName = metadata.getMethodName();

   // Do we need to mark the bean as skipped by its condition?
   if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
      configClass.skippedBeanMethods.add(methodName);
      return;
   }
   if (configClass.skippedBeanMethods.contains(methodName)) {
      return;
   }

   AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
   Assert.state(bean != null, "No @Bean annotation attributes");

   // 获取到@bean上的名字,第一个为beanName,后面的为别名,如:
   //@Bean({"user","2","3"})
   //public User user(){
   //System.out.println("1");
   //return new User();}
   List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
   //取出第一个beanName
   String beanName = (!names.isEmpty() ? names.remove(0) : methodName);

   // 将剩余的添加到别名
   for (String alias : names) {
      this.registry.registerAlias(beanName, alias);
   }

   //判断重复@Bean
   if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
      if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
         throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
               beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
               "' clashes with bean name for containing configuration class; please make those names unique!");
      }
      return;
   }

   ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
   beanDef.setResource(configClass.getResource());
   beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

   if (metadata.isStatic()) {
      // static @Bean method
      if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
         beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
      }
      else {
         beanDef.setBeanClassName(configClass.getMetadata().getClassName());
      }
      beanDef.setUniqueFactoryMethodName(methodName);
   }
   else {
      // instance @Bean method
      beanDef.setFactoryBeanName(configClass.getBeanName());
      beanDef.setUniqueFactoryMethodName(methodName);
   }

   if (metadata instanceof StandardMethodMetadata) {
      beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
   }
   //设置Bean注入方式为构造器注入
   beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
   beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
         SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

   AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);

   Autowire autowire = bean.getEnum("autowire");
   if (autowire.isAutowire()) {
      beanDef.setAutowireMode(autowire.value());
   }

   boolean autowireCandidate = bean.getBoolean("autowireCandidate");
   if (!autowireCandidate) {
      beanDef.setAutowireCandidate(false);
   }
    //设置bean的初始化和销毁方法
   String initMethodName = bean.getString("initMethod");
   if (StringUtils.hasText(initMethodName)) {
      beanDef.setInitMethodName(initMethodName);
   }

   String destroyMethodName = bean.getString("destroyMethod");
   beanDef.setDestroyMethodName(destroyMethodName);

   //设置bean的作用域
   ScopedProxyMode proxyMode = ScopedProxyMode.NO;
   AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
   if (attributes != null) {
      beanDef.setScope(attributes.getString("value"));
      proxyMode = attributes.getEnum("proxyMode");
      if (proxyMode == ScopedProxyMode.DEFAULT) {
         proxyMode = ScopedProxyMode.NO;
      }
   }

   // Replace the original bean definition with the target one, if necessary
   BeanDefinition beanDefToRegister = beanDef;
   if (proxyMode != ScopedProxyMode.NO) {
      BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
            new BeanDefinitionHolder(beanDef, beanName), this.registry,
            proxyMode == ScopedProxyMode.TARGET_CLASS);
      beanDefToRegister = new ConfigurationClassBeanDefinition(
            (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
   }

   if (logger.isTraceEnabled()) {
      logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
            configClass.getMetadata().getClassName(), beanName));
   }
   this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

看一下@Bean判重的方法isOverriddenByExistingDefinition(beanMethod, beanName)里面这一块逻辑

//用于判断beanName是否重复,重复的话只有第一个被注册
if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
   ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
   if (ccbd.getMetadata().getClassName().equals(
         beanMethod.getConfigurationClass().getMetadata().getClassName())) {
      if (ccbd.getFactoryMethodMetadata().getMethodName().equals(ccbd.getFactoryMethodName())) {
         ccbd.setNonUniqueFactoryMethodName(ccbd.getFactoryMethodMetadata().getMethodName());
      }
      return true;
   }
   else {
      return false;
   }
}

会先扫描@Component,再扫描@Bean

相对于@Component而言,@Bean中默认是允许被覆盖的,所以说最后@Bean生成的对象会保留下来。

被@Component注入的bd是ScannedGenericBeanDefinition,

被@Bean注入的db是ConfigurationClassBeanDefinition

如果两个都是@bean,beanName相同,则只会生成第一个。

一个小demo:

//同时一个@Component也有一个user对象,最终会生成的对象是第一个@Bean
@Bean
public User user(){
    System.out.println("1");
    return new User();             //最终会生成一个这一个user
}
@Bean("user")
public User user1(){
    System.out.println("2");
    return new User();
}

通过@Component得到的bean是通过autowire=no

通过@Bean得到的bean是通过构造方法的

 

关于@Configuration注解,生成代理对象的意义

@ComponentScan("com.chuan")
@Configuration
public class Config {
    @Bean
    public User user(){
        User user =new User();
        System.out.println("1"+user);
        return user;
    }
    @Bean
    public UserService userService(){
        User user =user();
        System.out.println("2"+user);
        return new UserService(user);
    }
}

结果为:

1com.chuan.model.User@551bdc27

2com.chuan.model.User@551bdc27

原理:因为该配置类被@Configuration标注了以后,创建了user之后放在了单例池里,之后创建userService时会让代理对象去单例池寻找,不会重复创建对象了。

源码里又提到了FactoryBean,到底怎么转成FactoryBean,需要再了解了解。

--这个FactoryBean指的就是该配置类,FactoryMethod是@Bean这个方法

总结:

解析Config(注册的配置类)类,生成对应的ConfigurationClass再扫描,扫描到的类都会生成对应的BeanDefinition,并且同时这些类也是ConfigurationClass再解ConfigurationClass的其他信息,比如@ImportResource注解的处理,@Import注解的处理,@Bean注解的处理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值