Spring系列(二) AnnotationConfigApplicationContext

AnnotationConfigApplicationContext

创建AnnotationConfigApplicationContext

  • 构造传入注解配置类,一步式解析 扫描 创建spring 容器
AnnotationConfigApplicationContext context 
    =new AnnotationConfigApplicationContext(AppConfig.class);

这种方式最简单,但不能预先添加自己的BeanFactoryPostProcessor到容器中优先于Spring内置的processor处理

如果有自定义的BeanDefinitionRegistryPostProcessor,会在spring内置处理器执行后以下阶段执行,通过beanDefinitionNames中取

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
     
 	reiterate = false;
 	postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 	...
 	currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 	...
 	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, 					  ...
}
  • 无参构造,逐步初始化
    不需要将BeanRegistryPostProcessor注册为bean时,可手动注册自定义的BeanRegistryPostProcessor后再,这时会优先执行自定义的processor

    AnnotationConfigApplicationContext ctx =new AnnotationConfigApplicationContext();
    //在invokeBeanFactoryPostProcessor时,取内部后置处理器可以取到
    ctx.addBeanFactoryPostProcessor(new CustomBeanRegistryPostProcessor());
    ctx.register(AppConfig.class);
    ctx.refresh();

register/scan

为容器中定义bean 寻找方式
  1. 传入注解类:AnnotatedBeanDefinitionReader先将该配置类封装为AnnotatedGenericBeanDefinition并通过registry注册该beanDefinition到容器中,在ConfigurationClassPostProcessor处理时会通过ConfigurationClassParser的doProcessConfigurationClass

    protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)  throws IOException {
           
    			  processMemberClasses(configClass, sourceClass);
    			  ...
                  		  Set<BeanDefinitionHolder> scannedBeanDefinitions =
    						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
    			...
    	}

    其中由ComponentScanAnnotationParser parse解析,里面再通过ClassPathBeanDefinitionScanner去扫描解析获得BeanDefinitionHolder,所扫面出来带注解的类将以ScannedGenericBeanDefinition形式存在beanFactory

    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
           
    		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
    		componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
    		...
    		return scanner.doScan(StringUtils.toStringArray(basePackages));
    }
  2. 传入包路径:使用ClassPathBeanDefinitionScanner扫描,将所有满足条件注解的bean封装为ScannedGenericBeanDefinition,注入容器.对有ComponentScan的同上进行ComponentScanAnnotationParser 后续处理(这种方式中,如果仍然还有加了@Configuration注解的类,ComponentScanAnnotationParser里将把该配置类exclude掉避免进行再次解析)

    scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
           
    			@Override
    			protected boolean matchClassName(String className) {
           
    				return declaringClass.equals(className);
    			}
    		});

refresh中重要方法解析

  1. prepareBeanFactory

    1. 设置类加载器
    2. 添加spring表达式解析器,用于解析SPEL; 添加ResourceEditorRegistrar
    3. 添加两个BeanPostProcessor :ApplicationContextAwareProcessor, ApplicationListenerDetector;以及是否需要添加LoadTimeWeaverAwareProcessor
    4. 往容器中添加3个系统 环境变量相关的bean,存入singletonObjects : [environment, systemProperties, systemEnvironment]
  2. invokeBeanFactoryPostProcessors

    1. 通过代理类PostProcessorRegistrationDelegate 调用容器中自己添加spring内置的后置处理器

      • 自己添加—>通过context.addBeanFactoryPostProcessor加入到beanFactoryPostProcessors集合中
      • spring内置—>AnnotationConfigUtils中注册的几个处理器
    2. 先处理自添加的BeanFactoryPostProcessor,如果是扩展的BeanRegistryPostProcessor 需要先调用postProcessBeanDefinitionRegistry,放入registryProcessors集合;一般BeanFactoryPostProcessor直接加入regularPostProcessors等待后面进行统一处理;

    3. 接着拿spring内置的BeanDefinitionRegistryPostProcessor,实际上只有一个ConfigurationClassPostProcessor,分别按优先级顺序进行处理,并实例化添加到beanFactory中

      String[] postProcessorNames= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)

      ConfigurationClassPostProcessor processConfigBeanDefinitions处理:

      1. 通过registry获取所有beanDefinition信息,逐一进行full/lite Configuration校验并为满足条件的bd标记attribute org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass为full/lite,初始化好configCandidates

        String[] candidateNames = registry.getBeanDefinitionNames();
        if(ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                   
        {
                   ...  } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)){
                   configCandidates.add(BeanDefinitionHolder)} 
      2. 将筛选出的config类进行下一步解析,经过ConfigurationClassParser parse和ConfigurationClassBeanDefinitionReader load所有需要扫描的bd

        // Parse each @Configuration class
        ConfigurationClassParser parser = new ConfigurationClassParser(
        		this.metadataReaderFactory,this.problemReporter,this.environment,
        	this.resourceLoader, this.componentScanBeanNameGenerator, registry);
        parser.parse(candidates);
      3. ConfigurationClassParser doProcessConfigurationClass会解析配置类上的PropertySources(PropertySource)、ComponentScans(ComponentScan)、Import 、Import Resource等注解,并对其中的config类再次进行处理

      4. 创建ConfigurationClassBeanDefinitionReader loadBeanDefinitions.其中会对Import、getBeanMethods、getImportedResources、getImportBeanDefinitionRegistrars这几种情况进一步处理引入的其他配置源

        this.reader = new ConfigurationClassBeanDefinitionReader(
              registry, this.sourceExtractor, this.resourceLoader,this.environment,
              this.importBeanNameGenerator, parser.getImportRegistry());
              this.reader.loadBeanDefinitions(configClasses);    
      5. 后续处理,添加org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry到容器中

    4. BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry都调用完后,将所有BeanFactoryPostProcessors的postProcessBeanFactory逐一执行

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

      ConfigurationClassPostProcessor 后置处理:

      1. enhanceConfigurationClasses(beanFactory)中,通过ConfigurationClassEnhancer对@Configuration注解的类进行CGLIB增强代理 ,注册了CALLBACKS:BeanMethodInterceptor, BeanFactoryAwareMethodInterceptor,NoOp.INSTANCE

        ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
        beanDef.setBeanClass(enhancedClass);
      2. 往容器中添加了一个ImportAwareBeanPostProcessor

    5. 从容器中获取目前所有的BeanFactoryPostProcessor,(spring内置的只有ConfigurationClassPostProcessor一个),按优先级排序最高的会先实例化保存下来,其余则拿到各自beanNames后再进行实例化并调用postProcessBeanFactory方法 继续调用前面未执行过的processor的postProcessBeanFactory

      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
                      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);
      			}
  3. finishBeanFactoryInitialization

    1. 在beanFactory 方法preInstantiateSingletons()中,会去实例化所有非懒加载的bean

    2. 初始化所有单例bean后,对SmartInitializingSingleton类型的进行afterSingletonsInstantiated调用

      1. 先从容器中找出注册并实例化好的EventListenerFactory,默认情况下得到DefaultEventListenerFactory

        List<EventListenerFactory> factories = getEventListenerFactories();
      2. 调用实例化后的回调方法

        for (String beanName : beanNames) {
                   
        			Object singletonInstance = getSingleton(beanName);
        			if (singletonInstance instanceof SmartInitializingSingleton) {
                   
        				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
        				...
        				smartSingleton.afterSingletonsInstantiated();
        				...
        			}
        		}
      3. 在spring内置的几个处理器中,有EventListenerMethodProcessor通过processBean处理,对有注解的方法进行处理

        protected void processBean( final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
                   
               		...
                     //选出有EventListener注解的方法存入annotatedMethods
        		if (CollectionUtils.isEmpty(annotatedMethods)) {
                   
        			this.nonAnnotatedClasses.add(targetType);
        			...
                       //return
        		}  else {
                   
                        ConfigurableApplicationContext context = getApplicationContext();
        				for (Method method : annotatedMethods.keySet()) {
                   
        					for (EventListenerFactory factory : factories) {
                   
        						if (factory.supportsMethod(method)) {
                   
        							Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
        							ApplicationListener<?> applicationListener =
        									factory.createApplicationListener(beanName, targetType, methodToUse);
        							if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                   
        								((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
        							}
        							context.addApplicationListener(applicationListener);
        							break;
        						}
        					}
        				}
                    }
        			}
      4. 通过传入的DefaultEventListenerFactory为注解方法创建ApplicationListener,并添加到容器中:ApplicationEventMulticaster和ApplicationContext的Set> applicationListeners中

        public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
                   
        		return new ApplicationListenerMethodAdapter(beanName, type, method);
        	}
  4. finishRefresh

    1. clearResourceCaches

    2. initLifecycleProcessor

    3. getLifecycleProcessor().onRefresh()

    4. publishEvent(new ContextRefreshedEvent(this))

      1. 由当前容器发布ContextRefreshedEvent,会通过SimpleApplicationEventMulticaster广播,前面加入的ApplictionListenr即ApplicationListenerMethodAdapter会通过listener.onApplicationEvent(event)收到该事件

        public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
                   
        		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
                   
        		...
        		invokeListener(listener, event);
        		...
        		}
        	}
      2. 加了EventListener注解的类方法会在收到对应事件,ApplicationListenerMethodAdapter processEvent(event)时被执行到

      3. 类似的,还有在容器关闭等发布对应事件publishEvent(new ContextClosedEvent(this)),也可以自定义需要的Event (扩展ApplicationContextEvent)

    5. LiveBeansView.registerApplicationContext(this)

Spring内置处理器

AnnotationConfigUtils是处理该配置类的核心,提供了解析配置类与注册注解PostProcessor的功能

registerAnnotationConfigProcessors

通过下图来简单描述下各自的作用
Spring系列(二) AnnotationConfigApplicationContext_第1张图片

ConfigurationClassPostProcessor.class
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
“org.springframework.context.annotation.internalConfigurationAnnotationProcessor”;

CONFIGURATION_BEAN_NAME_GENERATOR =
“org.springframework.context.annotation.internalConfigurationBeanNameGenerator”;

AutowiredAnnotationBeanPostProcessor.class
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
“org.springframework.context.annotation.internalAutowiredAnnotationProcessor”;

RequiredAnnotationBeanPostProcessor.class
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
“org.springframework.context.annotation.internalRequiredAnnotationProcessor”;

CommonAnnotationBeanPostProcessor.class
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
“org.springframework.context.annotation.internalCommonAnnotationProcessor”;

PersistenceAnnotationBeanPostProcessor.class
这个一般在jpa 存在[有引入javax.persistence.EntityManagerFactory 和spring-orm模块]时才会注册该processor
PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
“org.springframework.context.annotation.internalPersistenceAnnotationProcessor”;

PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME =
“org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor”;

EventListenerMethodProcessor.class
EVENT_LISTENER_PROCESSOR_BEAN_NAME =
“org.springframework.context.event.internalEventListenerProcessor”;

DefaultEventListenerFactory.class
EVENT_LISTENER_FACTORY_BEAN_NAME =
“org.springframework.context.event.internalEventListenerFactory”;

你可能感兴趣的:(spring,spring)