/** * Name of the MessageSource bean in the factory. * If none is supplied, message resolution is delegated to the parent. * @see MessageSource */ publicstaticfinalStringMESSAGE_SOURCE_BEAN_NAME="messageSource";
/** * Name of the LifecycleProcessor bean in the factory. * If none is supplied, a DefaultLifecycleProcessor is used. * @see org.springframework.context.LifecycleProcessor * @see org.springframework.context.support.DefaultLifecycleProcessor */ publicstaticfinalStringLIFECYCLE_PROCESSOR_BEAN_NAME="lifecycleProcessor";
/** * Name of the ApplicationEventMulticaster bean in the factory. * If none is supplied, a default SimpleApplicationEventMulticaster is used. * @see org.springframework.context.event.ApplicationEventMulticaster * @see org.springframework.context.event.SimpleApplicationEventMulticaster */ publicstaticfinalStringAPPLICATION_EVENT_MULTICASTER_BEAN_NAME="applicationEventMulticaster";
static { // Eagerly load the ContextClosedEvent class to avoid weird classloader issues // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.) ContextClosedEvent.class.getName(); }
/** Logger used by this class. Available to subclasses. */ protectedfinalLoglogger= LogFactory.getLog(getClass());
/** Unique id for this context, if any. */ privateStringid= ObjectUtils.identityToString(this);
// 一、Prepare this context for refreshing. prepareRefresh();
// 二、Tell the subclass to refresh the internal bean factory. // 调用实习 customizeBeanFactory 和 loadBeanDefinition ConfigurableListableBeanFactorybeanFactory= obtainFreshBeanFactory();
// 三、Prepare the bean factory for use in this context. // 一些需要提前加载的 Bean 注入(或者忽略)到 Spring 容器中 prepareBeanFactory(beanFactory);
try { // 四、Allows post-processing of the bean factory in context subclasses. // 四、运行 注册BeanFactoryProcessor 上下文注册 == 补充context postProcessBeanFactory(beanFactory);
StartupStepbeanPostProcess=this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); beanPostProcess.end();
// Initialize message source for this context. initMessageSource();
// Initialize event multicaster for this context. initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. onRefresh();
// Check for listener beans and register them. registerListeners();
// 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(); contextRefresh.end(); } } } }
/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */ protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(this, getEnvironment()));
// Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found. if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
// Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 获取系统的 properties参数 beanname,map if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 获取系统环境参数 beanname, map if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); } }
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
/** * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry. * <p>If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, * the {@link Environment} will be inherited, otherwise a new * {@link StandardEnvironment} will be created and used. * @param registry the {@code BeanFactory} to load bean definitions into, * in the form of a {@code BeanDefinitionRegistry} * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) * @see #setEnvironment(Environment) */ publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }
publicAnnotatedBeanDefinitionReader(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 = newConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } }
/** * Select and return the names of which class(es) should be imported based on * the {@link AnnotationMetadata} of the importing @{@link Configuration} class. * @return the class names, or an empty array if none */ String[] selectImports(AnnotationMetadata importingClassMetadata);
/** * Return a predicate for excluding classes from the import candidates, to be * transitively applied to all classes found through this selector's imports. * <p>If this predicate returns {@code true} for a given fully-qualified * class name, said class will not be considered as an imported configuration * class, bypassing class file loading as well as metadata introspection. * @return the filter predicate for fully-qualified candidate class names * of transitively imported configuration classes, or {@code null} if none * @since 5.2.4 */ @Nullable default Predicate<String> getExclusionFilter() { returnnull; }
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ StringFACTORY_BEAN_PREFIX="&";
Object getBean(String name)throws BeansException;
<T> T getBean(String name, Class<T> requiredType)throws BeansException;
/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ voidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException;
/** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ voidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)throws BeansException;
publicAnnotatedBeanDefinitionReader(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 = newConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } }
publicabstractclassAnnotationConfigUtils { /** * Register all relevant annotation post processors in the given registry. * @param registry the registry to operate on * @param source the configuration source element (already extracted) * that this registration was triggered from. May be {@code null}. * @return a Set of BeanDefinitionHolders, containing all bean definitions * that have actually been registered by this call */ publicstatic Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactorybeanFactory= unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { // AnnotationAwareOrderComparator if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { // ContextAnnotationAutowireCandidateResolver beanFactory.setAutowireCandidateResolver(newContextAnnotationAutowireCandidateResolver()); } }
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinitiondef=newRootBeanDefinition(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)) { RootBeanDefinitiondef=newRootBeanDefinition(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)) { RootBeanDefinitiondef=newRootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { thrownewIllegalStateException( "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)) { RootBeanDefinitiondef=newRootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // DefaultEventListenerFactory if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinitiondef=newRootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); }
// WARNING: Although it may appear that the body of this method can be easily // refactored to avoid the use of multiple loops and multiple lists, the use // of multiple lists and multiple passes over the names of processors is // intentional. We must ensure that we honor the contracts for PriorityOrdered // and Ordered processors. Specifically, we must NOT cause processors to be // instantiated (via getBean() invocations) or registered in the ApplicationContext // in the wrong order. // // Before submitting a pull request (PR) to change this method, please review the // list of all declined PRs involving changes to PostProcessorRegistrationDelegate // to ensure that your proposal does not result in a breaking change: // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) { registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } }
// Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = newArrayList<>();
// 2、PriorityOrdered 实现该接口的 BeanDefinitionRegistryPostProcessors 优先级最高 限制性 // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 2、getBean() 显示创建 ConfigurationClassPostProcessor实例 // (问题:何处将 BeanDefinition 注册到容器中) ==》(回答: 在初始化容器context的时候会初始化 read\scan ,在refresh的 方法 postProcessBeanFactory // 会调用 AbstractApplicationContext 的子类 ,web容器的 scan、register 方法,最终注册 BeanDefinition) // 在这,通过BeanFactory的 getBean方法,实例化所有已经注册的BeanDefinition 为 BeanDefinitionRegistryPostProcessor 的类 // 即,初始化 会初始化ConfigurationClassPostProcessor (问题:何处将 ConfigurationClassPostProcessor 注册为BeanDefinition?) // (回答:context 的 annotation 或者 scan 的时候自动注册,或者和BeanFactoryPostProcessor 一样被注册) // (具体回答:ConfigurationClassPostProcessor, 会在 AnnotationConfigServletWebServerApplicationContext ==》 AnnotatedBeanDefinitionReader 的 // 初始化过程中被 注册,因为这个 reader,会注册一些额外的 Processor增强器,实现一些功能) /** * * <p>Registered by default when using {@code <context:annotation-config/>} or * * {@code <context:component-scan/>}. Otherwise, may be declared manually as * * with any other {@link BeanFactoryPostProcessor}. */ currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 对 registerProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 优先调用postProcessBeanDefinitionRegistry // 调用 registerProcessor的 postProcessBeanDefinitionRegistry() invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear();
// 最后执行 普通的BeanDefinitionRegistryPostProcessors // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. booleanreiterate=true; while (reiterate) { reiterate = false; 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, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); }
// Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); }
else { // 执行容器的实例 // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }
// 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);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = newArrayList<>(); List<String> orderedPostProcessorNames = newArrayList<>(); List<String> nonOrderedPostProcessorNames = newArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } elseif (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } elseif (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
// Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = newArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = newArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
ConfigurationClassexistingClass=this.configurationClasses.get(configClass); if (existingClass != null) { if (configClass.isImported()) { if (existingClass.isImported()) { existingClass.mergeImportedBy(configClass); } // Otherwise ignore new imported config class; existing non-imported class overrides it. return; } else { // Explicit bean definition found, probably replacing an import. // Let's remove the old one and go with the new one. this.configurationClasses.remove(configClass); this.knownSuperclasses.values().removeIf(configClass::equals); } }
// Recursively process the configuration class and its superclass hierarchy. SourceClasssourceClass= asSourceClass(configClass, filter); do { // 具体 ConfigurationClass 的 解析 sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter); } while (sourceClass != null); // 添加 解析好的 configClass this.configurationClasses.put(configClass, configClass); }
if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // Recursively process any member (nested) classes first processMemberClasses(configClass, sourceClass, filter); }
// Process any @PropertySource annotations for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.propertySourceRegistry != null) { this.propertySourceRegistry.processPropertySource(propertySource); } else { logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } }
// Process any @ComponentScan annotations 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 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) { BeanDefinitionbdCand= holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // 关键 -- 自动注入 -- 实现接口,方法调用 // Process any @Import annotations processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations AnnotationAttributesimportResource= AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); if (importResource != null) { String[] resources = importResource.getStringArray("locations"); Class<? extendsBeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { StringresolvedResource=this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } }
// Process individual @Bean methods Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(newBeanMethod(methodMetadata, configClass)); }
// Process default methods on interfaces processInterfaces(configClass, sourceClass);
// Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { Stringsuperclass= 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 returnnull; }
/** * Read a particular {@link ConfigurationClass}, registering bean definitions * for the class itself and all of its {@link Bean} methods. */ privatevoidloadBeanDefinitionsForConfigurationClass( ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 如果 条件Condition判断 应当跳过当前配置类,则从当前registry中移除 BeanDefinition信息 if (trackedConditionEvaluator.shouldSkip(configClass)) { StringbeanName= configClass.getBeanName(); if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; }
/** * Invoked by the containing {@code BeanFactory} after it has set all bean properties * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc. * <p>This method allows the bean instance to perform validation of its overall * configuration and final initialization when all bean properties have been set. * @throws Exception in the event of misconfiguration (such as failure to set an * essential property) or if initialization fails for any other reason */ voidafterPropertiesSet()throws Exception;
/** * Obtain a reference for early access to the specified bean, * typically for the purpose of resolving a circular reference. * <p>This callback gives post-processors a chance to expose a wrapper * early - that is, before the target bean instance is fully initialized. * The exposed object should be equivalent to the what * {@link #postProcessBeforeInitialization} / {@link #postProcessAfterInitialization} * would expose otherwise. Note that the object returned by this method will * be used as bean reference unless the post-processor returns a different * wrapper from said post-process callbacks. In other words: Those post-process * callbacks may either eventually expose the same reference or alternatively * return the raw bean instance from those subsequent callbacks (if the wrapper * for the affected bean has been built for a call to this method already, * it will be exposes as final bean reference by default). * <p>The default implementation returns the given {@code bean} as-is. * @param bean the raw bean instance * @param beanName the name of the bean * @return the object to expose as bean reference * (typically with the passed-in bean instance as default) * @throws org.springframework.beans.BeansException in case of errors */ default Object getEarlyBeanReference(Object bean, String beanName)throws BeansException { return bean; }
/** * Post-process the given merged bean definition for the specified bean. * @param beanDefinition the merged bean definition for the bean * @param beanType the actual type of the managed bean instance * @param beanName the name of the bean * @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors */ voidpostProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/** * A notification that the bean definition for the specified name has been reset, * and that this post-processor should clear any metadata for the affected bean. * <p>The default implementation is empty. * @param beanName the name of the bean * @since 5.1 * @see DefaultListableBeanFactory#resetBeanDefinition */ defaultvoidresetBeanDefinition(String beanName) { }
/** * Register a new bean definition with this registry. * Must support RootBeanDefinition and ChildBeanDefinition. * @param beanName the name of the bean instance to register * @param beanDefinition definition of the bean instance to register * @throws BeanDefinitionStoreException if the BeanDefinition is invalid * @throws BeanDefinitionOverrideException if there is already a BeanDefinition * for the specified bean name and we are not allowed to override it * @see GenericBeanDefinition * @see RootBeanDefinition * @see ChildBeanDefinition */ voidregisterBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
/** * Remove the BeanDefinition for the given name. * @param beanName the name of the bean instance to register * @throws NoSuchBeanDefinitionException if there is no such bean definition */ voidremoveBeanDefinition(String beanName)throws NoSuchBeanDefinitionException;
/** * Return the BeanDefinition for the given bean name. * @param beanName name of the bean to find a definition for * @return the BeanDefinition for the given name (never {@code null}) * @throws NoSuchBeanDefinitionException if there is no such bean definition */ BeanDefinition getBeanDefinition(String beanName)throws NoSuchBeanDefinitionException;
/** * Check if this registry contains a bean definition with the given name. * @param beanName the name of the bean to look for * @return if this registry contains a bean definition with the given name */ booleancontainsBeanDefinition(String beanName);
/** * Return the names of all beans defined in this registry. * @return the names of all beans defined in this registry, * or an empty array if none defined */ String[] getBeanDefinitionNames();
/** * Return the number of beans defined in the registry. * @return the number of beans defined in the registry */ intgetBeanDefinitionCount();
/** * Determine whether the given bean name is already in use within this registry, * i.e. whether there is a local bean or alias registered under this name. * @param beanName the name to check * @return whether the given bean name is already in use */ booleanisBeanNameInUse(String beanName);
}
2.5 AnnotationConfigRegistry
web、servlet、react (web容器)的实现,注解扫描 注册 Bean
注解配置的 注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicinterfaceAnnotationConfigRegistry {
/** * Register one or more component classes to be processed. * <p>Calls to {@code register} are idempotent; adding the same * component class more than once has no additional effect. * @param componentClasses one or more component classes, * e.g. {@link Configuration @Configuration} classes */ voidregister(Class<?>... componentClasses);
/** * Perform a scan within the specified base packages. * @param basePackages the packages to scan for component classes */ voidscan(String... basePackages);
/** * The location to look for factories. * <p>Can be present in multiple JAR files. */ publicstaticfinalStringFACTORIES_RESOURCE_LOCATION="META-INF/spring.factories";
/** * Handle an application event. * @param event the event to respond to */ voidonApplicationEvent(E event);
/** * Create a new {@code ApplicationListener} for the given payload consumer. * @param consumer the event payload consumer * @param <T> the type of the event payload * @return a corresponding {@code ApplicationListener} instance * @since 5.3 * @see PayloadApplicationEvent */ static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) { return event -> consumer.accept(event.getPayload()); }
}
SpringApplicationRunListener - Spring Boot - Event
/** * Called immediately when the run method has first started. Can be used for very * early initialization. * @param bootstrapContext the bootstrap context */ defaultvoidstarting(ConfigurableBootstrapContext bootstrapContext) { }
/** * Called once the environment has been prepared, but before the * {@link ApplicationContext} has been created. * @param bootstrapContext the bootstrap context * @param environment the environment */ defaultvoidenvironmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) { }
/** * Called once the {@link ApplicationContext} has been created and prepared, but * before sources have been loaded. * @param context the application context */ defaultvoidcontextPrepared(ConfigurableApplicationContext context) { }
/** * Called once the application context has been loaded but before it has been * refreshed. * @param context the application context */ defaultvoidcontextLoaded(ConfigurableApplicationContext context) { }
/** * The context has been refreshed and the application has started but * {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner * ApplicationRunners} have not been called. * @param context the application context. * @param timeTaken the time taken to start the application or {@code null} if unknown * @since 2.6.0 */ defaultvoidstarted(ConfigurableApplicationContext context, Duration timeTaken) { started(context); }
/** * The context has been refreshed and the application has started but * {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner * ApplicationRunners} have not been called. * @param context the application context. * @since 2.0.0 * @deprecated since 2.6.0 for removal in 3.0.0 in favor of * {@link #started(ConfigurableApplicationContext, Duration)} */ @Deprecated defaultvoidstarted(ConfigurableApplicationContext context) { }
/** * Called immediately before the run method finishes, when the application context has * been refreshed and all {@link CommandLineRunner CommandLineRunners} and * {@link ApplicationRunner ApplicationRunners} have been called. * @param context the application context. * @param timeTaken the time taken for the application to be ready or {@code null} if * unknown * @since 2.6.0 */ defaultvoidready(ConfigurableApplicationContext context, Duration timeTaken) { running(context); }
/** * Called immediately before the run method finishes, when the application context has * been refreshed and all {@link CommandLineRunner CommandLineRunners} and * {@link ApplicationRunner ApplicationRunners} have been called. * @param context the application context. * @since 2.0.0 * @deprecated since 2.6.0 for removal in 3.0.0 in favor of * {@link #ready(ConfigurableApplicationContext, Duration)} */ @Deprecated defaultvoidrunning(ConfigurableApplicationContext context) { }
/** * Called when a failure occurs when running the application. * @param context the application context or {@code null} if a failure occurred before * the context was created * @param exception the failure * @since 2.0.0 */ defaultvoidfailed(ConfigurableApplicationContext context, Throwable exception) { }
@Override publicvoidfailed(ConfigurableApplicationContext context, Throwable exception) { ApplicationFailedEventevent=newApplicationFailedEvent(this.application, this.args, context, exception); if (context != null && context.isActive()) { // Listeners have been registered to the application context so we should // use it at this point if we can context.publishEvent(event); } else { // An inactive context may not have a multicaster so we use our multicaster to // call all the context's listeners instead if (context instanceof AbstractApplicationContext) { for (ApplicationListener<?> listener : ((AbstractApplicationContext) context) .getApplicationListeners()) { this.initialMulticaster.addApplicationListener(listener); } } this.initialMulticaster.setErrorHandler(newLoggingErrorHandler()); this.initialMulticaster.multicastEvent(event); } }
/** * Create a new {@link ApplicationPreparedEvent} instance. * @param application the current application * @param args the arguments the application is running with * @param context the ApplicationContext about to be refreshed */ publicApplicationPreparedEvent(SpringApplication application, String[] args, ConfigurableApplicationContext context) { super(application, args); this.context = context; }
/** * Return the application context. * @return the context */ public ConfigurableApplicationContext getApplicationContext() { returnthis.context; }
/** * Add a listener to be notified of all events. * @param listener the listener to add * @see #removeApplicationListener(ApplicationListener) * @see #removeApplicationListeners(Predicate) */ voidaddApplicationListener(ApplicationListener<?> listener);
/** * Add a listener bean to be notified of all events. * @param listenerBeanName the name of the listener bean to add * @see #removeApplicationListenerBean(String) * @see #removeApplicationListenerBeans(Predicate) */ voidaddApplicationListenerBean(String listenerBeanName);
/** * Remove a listener from the notification list. * @param listener the listener to remove * @see #addApplicationListener(ApplicationListener) * @see #removeApplicationListeners(Predicate) */ voidremoveApplicationListener(ApplicationListener<?> listener);
/** * Remove a listener bean from the notification list. * @param listenerBeanName the name of the listener bean to remove * @see #addApplicationListenerBean(String) * @see #removeApplicationListenerBeans(Predicate) */ voidremoveApplicationListenerBean(String listenerBeanName);
/** * Remove all matching listeners from the set of registered * {@code ApplicationListener} instances (which includes adapter classes * such as {@link ApplicationListenerMethodAdapter}, e.g. for annotated * {@link EventListener} methods). * <p>Note: This just applies to instance registrations, not to listeners * registered by bean name. * @param predicate the predicate to identify listener instances to remove, * e.g. checking {@link SmartApplicationListener#getListenerId()} * @since 5.3.5 * @see #addApplicationListener(ApplicationListener) * @see #removeApplicationListener(ApplicationListener) */ voidremoveApplicationListeners(Predicate<ApplicationListener<?>> predicate);
/** * Remove all matching listener beans from the set of registered * listener bean names (referring to bean classes which in turn * implement the {@link ApplicationListener} interface directly). * <p>Note: This just applies to bean name registrations, not to * programmatically registered {@code ApplicationListener} instances. * @param predicate the predicate to identify listener bean names to remove * @since 5.3.5 * @see #addApplicationListenerBean(String) * @see #removeApplicationListenerBean(String) */ voidremoveApplicationListenerBeans(Predicate<String> predicate);
/** * Remove all listeners registered with this multicaster. * <p>After a remove call, the multicaster will perform no action * on event notification until new listeners are registered. * @see #removeApplicationListeners(Predicate) */ voidremoveAllListeners();
/** * Multicast the given application event to appropriate listeners. * <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)} * if possible as it provides better support for generics-based events. * @param event the event to multicast */ voidmulticastEvent(ApplicationEvent event);
/** * Multicast the given application event to appropriate listeners. * <p>If the {@code eventType} is {@code null}, a default type is built * based on the {@code event} instance. * @param event the event to multicast * @param eventType the type of event (can be {@code null}) * @since 4.2 */ voidmulticastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
/** * Post-process the given {@code environment}. * @param environment the environment to post-process * @param application the application to which the environment belongs */ voidpostProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);
/** * Determine whether this listener actually supports the given event type. * @param eventType the event type (never {@code null}) */ booleansupportsEventType(Class<? extends ApplicationEvent> eventType);
/** * Determine whether this listener actually supports the given source type. * <p>The default implementation always returns {@code true}. * @param sourceType the source type, or {@code null} if no source */ defaultbooleansupportsSourceType(@Nullable Class<?> sourceType) { returntrue; }
/** * Determine this listener's order in a set of listeners for the same event. * <p>The default implementation returns {@link #LOWEST_PRECEDENCE}. */ @Override defaultintgetOrder() { return LOWEST_PRECEDENCE; }
/** * Return an optional identifier for the listener. * <p>The default value is an empty String. * @since 5.3.5 * @see EventListener#id * @see ApplicationEventMulticaster#removeApplicationListeners */ default String getListenerId() { return""; }
/** * Environment property that can be used to override when auto-configuration is * enabled. */ StringENABLED_OVERRIDE_PROPERTY="spring.boot.enableautoconfiguration";
/** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class<?>[] exclude() default {};
/** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {};
/** * Create a new {@link SpringApplication} instance. The application context will load * beans from the specified primary sources (see {@link SpringApplication class-level} * documentation for details). The instance can be customized before calling * {@link #run(String...)}. * @param resourceLoader the resource loader to use * @param primarySources the primary bean sources * @see #run(Class, String[]) * @see #setSources(Set) */