spring 随笔 ioc/di 4-Bean生命周期钩子
0. RUN,或8RUN,是每年都会思考的问题
Spring框架后置处理器PostProcessor详解
BeanDefinitionRegistryPostProcessor 扩展接口 动态注册bean
AOP的高级特性targetSource
AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation源码解析
通勤路上,刷到好文,遂debug,而后得此文…
1. 先放一下 AbstractApplicationContext.refresh()
虽然跟本文的要点联系不大,这里补充说明一下之前随笔的时候草率的地方
// org.springframework.context.support.AbstractApplicationContext#refresh// 当前的 applicationContext=AnnotationConfigServletWebServerApplicationContext@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.// 进一步准备上下文配置而已,与beanFactory、bean的生命周期不大相关prepareRefresh();// 这里基本毫无逻辑,return applicationContext.beanFactory而已// 这里的beanFactory其实就是 this.beanFactory(注:this=ApplicationContext)// ApplicationContext 内部维护了属性 beanFactory// 虽然当前 applicationContext 与 beanFactory 同源// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// #2// step into ...// 为beanFactory注册(register)几个比较特殊的bean// 为beanFactory添加(add)了几个比较特殊的BeanPostProcessor// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// #3// 回调 BeanFactory 的钩子// step into ...// 也算是add了个比较特殊的BeanPostProcessor// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// #4// step into ...// 执行 beanFactory 的后置处理器 BeanFactoryPostProcessor// 剧透是被允许的:@Component最终作为BeanDefinition将被注册 beanFactory// 没错:BeanDefinition的解析、注册作为beanFactory的后置处理逻辑了// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// 不谈// 注册beanPostProcessor到beanFactory// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// 国际化以后再说吧// 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();// #5// step into ...// beanPostProcessor也是在这里被回调// Instantiate all remaining (non-lazy-init) singletons.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();}}}
1.1 BeanFactory的初始化此时已经完成
本文使用的spring版本中,注解支持的webApplicationContext的实例化、初始化的位置,经确认,确实要早很多
applicationContext内部维护的beanFactory在其初始化的过程中,就已经完成了自己的初始化,AbstractApplicationContext.refresh()阶段只是注册、执行了几个BeanFactoryPostProcessor,回调bean工厂的钩子而已。
// applicationContext.beanFactory 在其父类的空构造中实例化
<init>:112, GenericApplicationContext (org.springframework.context.support)
<init>:81, GenericWebApplicationContext (org.springframework.web.context.support)
<init>:117, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
<init>:72, AnnotationConfigServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:423, Constructor (java.lang.reflect)
instantiateClass:204, BeanUtils (org.springframework.beans)
instantiateClass:139, BeanUtils (org.springframework.beans)
// 以上spring的工具类反射调用默认的(空)构造而已
// 可以看到 application.beanFactory 初始化的位置很早
createApplicationContext:588, SpringApplication (org.springframework.boot)
run:311, SpringApplication (org.springframework.boot)
run:1237, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
main:10, AngelMicroServiceSampleApplication (cn.angel.project.angelmicroservicesample)-----------// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContextimplements AnnotationConfigRegistry {// 此时applicationContext的注解扫描器、类路径读取器均实例化private final AnnotatedBeanDefinitionReader reader;private final ClassPathBeanDefinitionScanner scanner;public AnnotationConfigServletWebServerApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
}------------// org.springframework.context.support.GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {private final DefaultListableBeanFactory beanFactory;/* Create a new GenericApplicationContext.* @see #registerBeanDefinition* @see #refresh*/public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}
}
2. prepareBeanFactory(beanFactory)
// org.springframework.context.support.AbstractApplicationContext#prepareBeanFactoryprotected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 掠过beanFactory表达式处理器、类加载器的设置// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 配置了 beanFactory 在上下文中的回调 beanFactory.addBeanPostProcessor// class ApplicationContextAwareProcessor implements BeanPostProcessor// 注意这个 BeanPostProcesser 的作用域是 default// 该 BeanPostProcesser 用于给同一包下的 Aware 赋值 this.applicationContext 引用// Configure the bean factory with context callbacks.beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 暂时放过这个监听器相关的 BeanPostProcessor// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {// 加载计时使用的 BeanPostProcesser ,也同样掠过beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}
3. postProcessBeanFactory(beanFactory)
// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory@Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// step into ...super.postProcessBeanFactory(beanFactory);// 此时,下面俩if均为false,当前这不重要if (this.basePackages != null && this.basePackages.length > 0) {this.scanner.scan(this.basePackages);}if (!this.annotatedClasses.isEmpty()) {this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));}}// org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#postProcessBeanFactory@Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 又逮到辣 beanFactory.addBeanPostProcessor// WebApplicationContextServletContextAwareProcessor extends ServletContextAwareProcessor// ServletContextAwareProcessor implements BeanPostProcessor// 也是用来给其他 BeanPostProcessor Servlet相关的Aware 供血的// 助其赋值 ServletConfig、ServletContextbeanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ServletContextAware.class);registerWebApplicationScopes();}
4. invokeBeanFactoryPostProcessors(beanFactory)
这一小节有点小长,但是之前也确认遗漏了这一块,总之就是 @Component 变 BeanDefinition
// org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessorsprotected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// step into ...// 众所周知,前面实例化、初始化 beanFactory 的时候都没有往里面解析、注册过我们注解的component的beanDefinition// 原来是放在这里做了(作为 beanFactory 的后置处理器的回调逻辑)// 这里的getBeanFactoryPostProcessors()是applicationContextdePostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}// org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)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<>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;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 = new ArrayList<>();// 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)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);// step into ...// 不墨迹,这里走// 就这一个方法就出现三次 invokeBeanDefinitionRegistryPostProcessors// 分别是对应不同的优先级的bean的注册(@Ordered、@PriorityOrdered这些)// 我们自定义的 BeanDefinitionRegistryPostProcessor 实现类也会照优先级在这里被调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.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();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate = 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);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 = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {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.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.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.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(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();}// org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessorsprivate static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {// step into ...// 循环执行 beanFactory 的后置处理器嘛// 我们关心的、用于解析、注册@Component类并缓存成beanDefinition的后置处理器// ConfigurationClassPostProcessorpostProcessor.postProcessBeanDefinitionRegistry(registry);}}// org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {// 暂时掠过这坨 beanDefinition注册过程 绑定具体的注册器的逻辑int registryId = System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}this.registriesPostProcessed.add(registryId);// step into ...processConfigBeanDefinitions(registry);}// org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitionspublic void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();String[] candidateNames = registry.getBeanDefinitionNames();for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);}}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// Return immediately if no @Configuration classes were foundif (configCandidates.isEmpty()) {return;}// Sort by previously determined @Order value, if applicableconfigCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());return Integer.compare(i1, i2);});// Detect any custom bean name generation strategy supplied through the enclosing application contextSingletonBeanRegistry sbr = null;if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);if (generator != null) {this.componentScanBeanNameGenerator = generator;this.importBeanNameGenerator = generator;}}}if (this.environment == null) {this.environment = new StandardEnvironment();}// 解析javaConfig配置类,所用来的parser// 可以看到事先准备的几个类// Parse each @Configuration classConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());do {// step into ...// 这个候选(candidates)集合仅有我们的启动类// 为什么是启动类呢,其实很好理解:// @SpringBootApplication -> @SpringBootConfiguration -> @Configurationparser.parse(candidates);parser.validate();Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);// Read the model and create bean definitions based on its contentif (this.reader == null) {this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);candidates.clear();if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));Set<String> alreadyParsedClasses = new HashSet<>();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames = newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classesif (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {// Clear cache in externally provided MetadataReaderFactory; this is a no-op// for a shared cache since it'll be cleared by the ApplicationContext.((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}}// org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)public void parse(Set<BeanDefinitionHolder> configCandidates) {for (BeanDefinitionHolder holder : configCandidates) {BeanDefinition bd = holder.getBeanDefinition();try {if (bd instanceof AnnotatedBeanDefinition) {// step into ...// 我们的启动类是注解标记的,没啥好说的parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());}else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());}else {parse(bd.getBeanClassName(), holder.getBeanName());}}catch (BeanDefinitionStoreException ex) {throw ex;}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);}}this.deferredImportSelectorHandler.process();}// org.springframework.context.annotation.ConfigurationClassParser#parse(org.springframework.core.type.AnnotationMetadata, java.lang.String)protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {// step into ...processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);}// org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClassprotected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}ConfigurationClass existingClass = 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.SourceClass sourceClass = asSourceClass(configClass, filter);do {// step into ...sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass != null);this.configurationClasses.put(configClass, configClass);}// org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass@Nullableprotected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// Recursively process any member (nested) classes firstprocessMemberClasses(configClass, sourceClass, filter);}// Process any @PropertySource annotationsfor (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 annotationsSet<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) {// step into ...// 可以说接下来,从配置类(启动类)的层面 下到 扫描的类路径的层面// 注:此时的类路径还有可能存在通配符,还需要一次解析的loop// The config class is annotated with @ComponentScan -> perform the scan immediatelySet<BeanDefinitionHolder> scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}// Process any @Import annotationsprocessImports(configClass, sourceClass, getImports(sourceClass), filter, true);// Process any @ImportResource annotationsAnnotationAttributes 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 methodsSet<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// Process default methods on interfacesprocessInterfaces(configClass, sourceClass);// Process superclass, if anyif (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 recursereturn sourceClass.getSuperClass();}}// No superclass -> processing is completereturn null;}// org.springframework.context.annotation.ComponentScanAnnotationParser#parsepublic Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :BeanUtils.instantiateClass(generatorClass));ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");if (scopedProxyMode != ScopedProxyMode.DEFAULT) {scanner.setScopedProxyMode(scopedProxyMode);}else {Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));}scanner.setResourcePattern(componentScan.getString("resourcePattern"));for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {for (TypeFilter typeFilter : typeFiltersFor(filter)) {scanner.addIncludeFilter(typeFilter);}}for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {for (TypeFilter typeFilter : typeFiltersFor(filter)) {scanner.addExcludeFilter(typeFilter);}}boolean lazyInit = componentScan.getBoolean("lazyInit");if (lazyInit) {scanner.getBeanDefinitionDefaults().setLazyInit(true);}// 看的出来吧,将1条待通配符的类路径解析成多条具体的类路径Set<String> basePackages = new LinkedHashSet<>();String[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg : basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});// step into ...return scanner.doScan(StringUtils.toStringArray(basePackages));}// org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScanprotected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();// 等的就是这个循环,从此明确1条类路径for (String basePackage : basePackages) {// 查找该类路径下所有直接、间接的@Component类// 封装逻辑: @Component -> BeanDefinition// MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);// ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);Set<BeanDefinition> candidates = findCandidateComponents(basePackage);// 这个循环来for (BeanDefinition candidate : candidates) {ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}if (checkCandidate(beanName, candidate)) {// BeanDefinitionHolder 一般是spring.ioc内部使用的了// 内部维护了 beanDefinition、beanName、alias 而已BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);// 最终可达 org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition// 即: concurrentHashmap.put// beanDefinitionMap// 所以到此结束,童叟无欺registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}
5. finishBeanFactoryInitialization(beanFactory)
这里很多源码跟之前的随笔重复了,这里直接给bean创建、初始化时候的源码,不再赘述不相关的地方
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation// 常见的实现:AOP相关的(aspectj)在这里返回代理类// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {// 如果实例化的前置处理 真返回出来了,就不再走下面的流程了return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}----------// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBeanprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// bean 实例化instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 看到 applyXxxPostProcessors,我就魔怔了// MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition// 查找、校验、缓存 bean对应的metadata(元数据)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {// bean 属性装配populateBean(beanName, mbd, instanceWrapper);// bean 初始化exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}------------// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBeanprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {// Skip property population phase for null instance.return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation// bean 实例化 的后置处理返回 true/false// 翻了下,没啥有用的实现if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);int resolvedAutowireMode = mbd.getResolvedAutowireMode();if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// InstantiationAwareBeanPostProcessor.postProcessPropertyValues// AutowiredAnnotationBeanPostProcessor 可以用于对 @Autowired、@Value 注解的依赖进行设值pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}}------------// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// BeanPostProcessor.postProcessBeforeInitialization// 执行当前类中生命周期的方法,例如:@PostConstructwrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 如果当前bean impl InitializingBean// InitializingBean 适合spring.ioc.bean初始化,此时对象已经完成初始化、自动注入// 那么这里会调用执行invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {// BeanPostProcessor.postProcessAfterInitialization// spring.aop也利用这个扩展了代理对象的返回时机// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitializationwrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
6. 为加深印象,这里削微地呼应一下aop的随笔
- 不要忘了,AbstractAutoProxyCreator所有类无论需不需要被代理都会执行其bpp回调
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {Object cacheKey = getCacheKey(beanClass, beanName);if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}// isInfrastructureClass() 是否aop相关的基础类:advise、aspect...// shouldSkip() 也类似,即如果当前bean是aop相关class,跳过if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// targetSource 为内存中真实对象的包装类// 如果存在该 targetSource,则返回1个代理实例// 存在targetSource也代表着,该bean的管理方式不再与spring.ioc强相关// 多例实例可以借助targetSource实现同一个代理实例// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {if (StringUtils.hasLength(beanName)) {this.targetSourcedBeans.add(beanName);}Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}return null;}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) {return true;}@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {return pvs;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}/* Create a proxy with the configured interceptors if the bean is* identified as one to proxy by the subclass.* @see #getAdvicesAndAdvisorsForBean*/@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {// 如果earlyProxyReferences没有缓存当前bean(真实实例),那么包装1个代理实例返回if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}
7. 小结
- bean生命周期:class -> metadata -> beanDefinition -> 实例化 -> 属性、依赖赋值 -> 初始化
- 像javax.@PostConstruct、spring.ioc依赖自动注入、spring.aop的代理实例返回 等操作均是 BeanPostProcessor 方式实现的
- BeanPostProcessor 是spring提供的bean、beanFactory的生命周期钩子,spring的ioc、aop实现中也是如此践行的