// Prepare this context for refreshing. prepareRefresh();
// Tell the subclass to refresh the internal bean factory. // 通过各种Context(xml,annotation,groovy) ## loadBeanDefinitions()加载BeanDefinition到当前的 //用于记载BeanDefinition ConfigurableListableBeanFactorybeanFactory= obtainFreshBeanFactory();
// Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);
try { // Allows post-processing of the bean factory in context subclasses. 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();
// Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. finishRefresh(); }
// 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(); } } }
// 内部类 InjectedElement : 两个子类 // AutowiredFieldElement(自动注入属性) AutowiredMethodElement(自动注入方法) publicabstractstaticclassInjectedElement { // java.lang.reflect == a single member (a field or a method) or a constructor. // 一个属性、一个方法或者一个构造方法 protectedfinal Member member; protectedfinalboolean isField;
/** use serialVersionUID from Spring 2.0 for interoperability. */ privatestaticfinallongserialVersionUID=2651364800145442165L;
/** * Canonical TargetSource when there's no target, and behavior is * supplied by the advisors. */ publicstaticfinalTargetSourceEMPTY_TARGET_SOURCE= EmptyTargetSource.INSTANCE;
/** Package-protected to allow direct access for efficiency. */ TargetSourcetargetSource= EMPTY_TARGET_SOURCE;
/** Whether the Advisors are already filtered for the specific target class. */ privatebooleanpreFiltered=false;
/** The AdvisorChainFactory to use. */ AdvisorChainFactoryadvisorChainFactory=newDefaultAdvisorChainFactory();
/** Cache with Method as key and advisor chain List as value. */ privatetransient Map<MethodCacheKey, List<Object>> methodCache;
/** * Interfaces to be implemented by the proxy. Held in List to keep the order * of registration, to create JDK proxy with specified order of interfaces. */ private List<Class<?>> interfaces = newArrayList<>();
/** * List of Advisors. If an Advice is added, it will be wrapped * in an Advisor before being added to this List. */ private List<Advisor> advisors = newArrayList<>();
/** * Create an {@link AopProxy} for the given AOP configuration. * @param config the AOP configuration in the form of an * AdvisedSupport object * @return the corresponding AOP proxy * @throws AopConfigException if the configuration is invalid */ AopProxy createAopProxy(AdvisedSupport config)throws AopConfigException;
@Override public AopProxy createAopProxy(AdvisedSupport config)throws AopConfigException { if (!NativeDetector.inNativeImage() && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { thrownewAopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) { returnnewJdkDynamicAopProxy(config); } returnnewObjenesisCglibAopProxy(config); } else { returnnewJdkDynamicAopProxy(config); } }
TargetClassAware
1 2 3 4 5 6 7 8 9 10 11
publicinterfaceTargetClassAware {
/** * Return the target class behind the implementing object * (typically a proxy configuration or an actual proxy). * @return the target Class, or {@code null} if not known */ @Nullable Class<?> getTargetClass();
/** * Create a new proxy object. * <p>Uses the AopProxy's default class loader (if necessary for proxy creation): * usually, the thread context class loader. * @return the new proxy object (never {@code null}) * @see Thread#getContextClassLoader() */ Object getProxy();
/** * Create a new proxy object. * <p>Uses the given class loader (if necessary for proxy creation). * {@code null} will simply be passed down and thus lead to the low-level * proxy facility's default, which is usually different from the default chosen * by the AopProxy implementation's {@link #getProxy()} method. * @param classLoader the class loader to create the proxy with * (or {@code null} for the low-level proxy facility's default) * @return the new proxy object (never {@code null}) */ Object getProxy(@Nullable ClassLoader classLoader);
/** Config used to configure this proxy. */ privatefinal AdvisedSupport advised; @Override public Object getProxy() { return getProxy(ClassUtils.getDefaultClassLoader()); }
// Constants for CGLIB callback array indices privatestaticfinalintAOP_PROXY=0; privatestaticfinalintINVOKE_TARGET=1; privatestaticfinalintNO_OVERRIDE=2; privatestaticfinalintDISPATCH_TARGET=3; privatestaticfinalintDISPATCH_ADVISED=4; privatestaticfinalintINVOKE_EQUALS=5; privatestaticfinalintINVOKE_HASHCODE=6;
/** Logger available to subclasses; static to optimize serialization. */ protectedstaticfinalLoglogger= LogFactory.getLog(CglibAopProxy.class);
/** Keeps track of the Classes that we have validated for final methods. */ privatestaticfinal Map<Class<?>, Boolean> validatedClasses = newWeakHashMap<>();
/** The configuration used to configure this proxy. */ protectedfinal AdvisedSupport advised; @Override public Object getProxy() { return getProxy(null); }
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); }
try { Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = newClass<?>[callbacks.length]; for (intx=0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(newProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { thrownewAopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed thrownewAopConfigException("Unexpected AOP exception", ex); } } }
// 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
// Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = newHashSet<>();
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<>();
// 最后执行 普通的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); } }
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 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(); } publicstaticvoidregisterBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 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
// Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. intbeanProcessorTargetCount= beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(newBeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = newArrayList<>(); List<BeanPostProcessor> internalPostProcessors = newArrayList<>(); List<String> orderedPostProcessorNames = newArrayList<>(); List<String> nonOrderedPostProcessorNames = newArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 实例化 BeanPostProcessor BeanPostProcessorpp= beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } elseif (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 分多个等级注册 PriorityOrdered, Ordered, regular(常规), internal BeanPostProcessors
// First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered. List<BeanPostProcessor> orderedPostProcessors = newArrayList<>(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { BeanPostProcessorpp= beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = newArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessorpp= beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(newApplicationListenerDetector(applicationContext)); } }
// 方法invokeBeanFactoryPostProcessors() ## postProcessBeanFactory() @Override publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { intfactoryId= System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { thrownewIllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. // 调用创建 ConfigurationClass processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); }
for (String beanName : candidateNames) { BeanDefinitionbeanDef= 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); } } // 通过 ji // ConfigurationClass // Check whether the given bean definition is a candidate for a configuration class // 检查是否满足 配置类候选者 条件 elseif (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(newBeanDefinitionHolder(beanDef, beanName)); } }
// Return immediately if no @Configuration classes were found if (configCandidates.isEmpty()) { return; }
// Read the model and create bean definitions based on its content // 读取模式,并基于ConfigurationClass信息创建beanDefinition if (this.reader == null) { // 初始化 ConfigurationClassBeanDefinitionReader this.reader = newConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } // 调用reader.loadBeanDefinitions() // 将configClasses注册为BeanDefinition // 加载BeanDefinition -》 this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = Set.of(candidateNames); Set<String> alreadyParsedClasses = newHashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinitionbd= registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(newBeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); }
// Store the PropertySourceDescriptors to contribute them Ahead-of-time if necessary this.propertySourceDescriptors = parser.getPropertySourceDescriptors();
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory 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.clearCache(); } } }
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; }
/*Indicates one or more resources containing bean definitions to import*/ // 导入 BeanDefinition资源 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public@interface ImportResource {
/** * Alias for {@link #locations}. * @see #locations * @see #reader */ @AliasFor("locations") String[] value() default {};
/** * Resource locations from which to import. * <p>Supports resource-loading prefixes such as {@code classpath:}, * {@code file:}, etc. * <p>Consult the Javadoc for {@link #reader} for details on how resources * will be processed. * @since 4.2 * @see #value * @see #reader */ @AliasFor("value") String[] locations() default {};
/** * {@link BeanDefinitionReader} implementation to use when processing * resources specified via the {@link #value} attribute. * <p>By default, the reader will be adapted to the resource path specified: * {@code ".groovy"} files will be processed with a * {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader GroovyBeanDefinitionReader}; * whereas, all other resources will be processed with an * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader XmlBeanDefinitionReader}. * @see #value */ Class<? extendsBeanDefinitionReader> reader() default BeanDefinitionReader.class;
/** * 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; }
/** * Interface that defines Spring-compliant transaction properties. * Based on the propagation behavior definitions analogous to EJB CMT attributes. * * <p>Note that isolation level and timeout settings will not get applied unless * an actual new transaction gets started. As only {@link #PROPAGATION_REQUIRED}, * {@link #PROPAGATION_REQUIRES_NEW}, and {@link #PROPAGATION_NESTED} can cause * that, it usually doesn't make sense to specify those settings in other cases. * Furthermore, be aware that not all transaction managers will support those * advanced features and thus might throw corresponding exceptions when given * non-default values. * * <p>The {@linkplain #isReadOnly() read-only flag} applies to any transaction context, * whether backed by an actual resource transaction or operating non-transactionally * at the resource level. In the latter case, the flag will only apply to managed * resources within the application, such as a Hibernate {@code Session}.
/** * Support a current transaction; create a new one if none exists. * Analogous to the EJB transaction attribute of the same name. * <p>This is typically the default setting of a transaction definition * and typically defines a transaction synchronization scope. */ intPROPAGATION_REQUIRED=0;
/** * Support a current transaction; execute non-transactionally if none exists. * Analogous to the EJB transaction attribute of the same name. * <p><b>NOTE:</b> For transaction managers with transaction synchronization, * {@code PROPAGATION_SUPPORTS} is slightly different from no transaction * at all, as it defines a transaction scope that synchronization might apply to. * As a consequence, the same resources (a JDBC {@code Connection}, a * Hibernate {@code Session}, etc) will be shared for the entire specified * scope. Note that the exact behavior depends on the actual synchronization * configuration of the transaction manager. * <p>In general, use {@code PROPAGATION_SUPPORTS} with care. In particular, do * not rely on {@code PROPAGATION_REQUIRED} or {@code PROPAGATION_REQUIRES_NEW} * <i>within</i> a {@code PROPAGATION_SUPPORTS} scope (which may lead to * synchronization conflicts at runtime). If such nesting is unavoidable, make sure * to configure your transaction manager appropriately (typically switching to * "synchronization on actual transaction"). * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#SYNCHRONIZATION_ON_ACTUAL_TRANSACTION */ intPROPAGATION_SUPPORTS=1;
/** * Support a current transaction; throw an exception if no current transaction * exists. Analogous to the EJB transaction attribute of the same name. * <p>Note that transaction synchronization within a {@code PROPAGATION_MANDATORY} * scope will always be driven by the surrounding transaction. */ intPROPAGATION_MANDATORY=2;
/** * Create a new transaction, suspending the current transaction if one exists. * Analogous to the EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code jakarta.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Jakarta EE). * <p>A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own * transaction synchronizations. Existing synchronizations will be suspended * and resumed appropriately. * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ intPROPAGATION_REQUIRES_NEW=3;
/** * Do not support a current transaction; rather always execute non-transactionally. * Analogous to the EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code jakarta.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Jakarta EE). * <p>Note that transaction synchronization is <i>not</i> available within a * {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations * will be suspended and resumed appropriately. * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ intPROPAGATION_NOT_SUPPORTED=4;
/** * Do not support a current transaction; throw an exception if a current transaction * exists. Analogous to the EJB transaction attribute of the same name. * <p>Note that transaction synchronization is <i>not</i> available within a * {@code PROPAGATION_NEVER} scope. */ intPROPAGATION_NEVER=5;
intISOLATION_READ_UNCOMMITTED=1; // same as java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
intISOLATION_READ_COMMITTED=2; // same as java.sql.Connection.TRANSACTION_READ_COMMITTED;
intISOLATION_REPEATABLE_READ=4; // same as java.sql.Connection.TRANSACTION_REPEATABLE_READ;
intISOLATION_SERIALIZABLE=8; // same as java.sql.Connection.TRANSACTION_SERIALIZABLE;
/** * Use the default timeout of the underlying transaction system, * or none if timeouts are not supported. */ intTIMEOUT_DEFAULT= -1;
/** * Return the propagation behavior. * <p>Must return one of the {@code PROPAGATION_XXX} constants * defined on {@link TransactionDefinition this interface}. * <p>The default is {@link #PROPAGATION_REQUIRED}. * @return the propagation behavior * @see #PROPAGATION_REQUIRED * @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive() */ defaultintgetPropagationBehavior() { return PROPAGATION_REQUIRED; }
/** * Return the isolation level. * <p>Must return one of the {@code ISOLATION_XXX} constants defined on * {@link TransactionDefinition this interface}. Those constants are designed * to match the values of the same constants on {@link java.sql.Connection}. * <p>Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started * transactions. Consider switching the "validateExistingTransactions" flag to * "true" on your transaction manager if you'd like isolation level declarations * to get rejected when participating in an existing transaction with a different * isolation level. * <p>The default is {@link #ISOLATION_DEFAULT}. Note that a transaction manager * that does not support custom isolation levels will throw an exception when * given any other level than {@link #ISOLATION_DEFAULT}. * @return the isolation level * @see #ISOLATION_DEFAULT * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction */ defaultintgetIsolationLevel() { return ISOLATION_DEFAULT; }
/** * Return the transaction timeout. * <p>Must return a number of seconds, or {@link #TIMEOUT_DEFAULT}. * <p>Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started * transactions. * <p>Note that a transaction manager that does not support timeouts will throw * an exception when given any other timeout than {@link #TIMEOUT_DEFAULT}. * <p>The default is {@link #TIMEOUT_DEFAULT}. * @return the transaction timeout */ defaultintgetTimeout() { return TIMEOUT_DEFAULT; }
/** * Return whether to optimize as a read-only transaction. * <p>The read-only flag applies to any transaction context, whether backed * by an actual resource transaction ({@link #PROPAGATION_REQUIRED}/ * {@link #PROPAGATION_REQUIRES_NEW}) or operating non-transactionally at * the resource level ({@link #PROPAGATION_SUPPORTS}). In the latter case, * the flag will only apply to managed resources within the application, * such as a Hibernate {@code Session}. * <p>This just serves as a hint for the actual transaction subsystem; * it will <i>not necessarily</i> cause failure of write access attempts. * A transaction manager which cannot interpret the read-only hint will * <i>not</i> throw an exception when asked for a read-only transaction. * @return {@code true} if the transaction is to be optimized as read-only * ({@code false} by default) * @see org.springframework.transaction.support.TransactionSynchronization#beforeCommit(boolean) * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() */ defaultbooleanisReadOnly() { returnfalse; }
/** * Return the name of this transaction. Can be {@code null}. * <p>This will be used as the transaction name to be shown in a * transaction monitor, if applicable (for example, WebLogic's). * <p>In case of Spring's declarative transactions, the exposed name will be * the {@code fully-qualified class name + "." + method name} (by default). * @return the name of this transaction ({@code null} by default} * @see org.springframework.transaction.interceptor.TransactionAspectSupport * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionName() */ @Nullable default String getName() { returnnull; }
// Static builder methods
/** * Return an unmodifiable {@code TransactionDefinition} with defaults. */ static TransactionDefinition withDefaults() { return StaticTransactionDefinition.INSTANCE; }
}
1 2 3 4 5 6 7 8
// since spring 5.2 publicinterfacePlatformTransactionManagerextendsTransactionManager { TransactionStatus getTransaction(@Nullable TransactionDefinition var1)throws TransactionException;
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc-portlet</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webflux</artifactId> <version>${org.springframework.version}</version> </dependency> <!--spring web end -->
<!--spring test start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework.version}</version> </dependency> <!--spring test end --> <!-- spring end --> </dependencies>
packaget-info.java
1 2 3 4 5
1、为标注在包上Annotation提供便利;
2、声明友好类和包常量;
3、提供包的整体注释说明。
1 2 3 4 5 6 7 8 9 10 11
/** * Classes supporting the org.springframework.context package, * such as abstract base classes for ApplicationContext * implementations and a MessageSource implementation. */ @NonNullApi 用于声明参数和返回值在默认情况下对于给定的包被视为不可为空。 @NonNullFields 用于声明对于给定的包,默认情况下字段将被视为不可为空 package org.springframework.context.support;
// Destroy already created singletons to avoid dangling resources. // 销毁已经创建的Bean 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(); } } }
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); }
// Check for Jakarta Annotations support, and if present add the CommonAnnotationBeanPostProcessor. if ((jakartaAnnotationsPresent || 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)); }
// JPA 相关的支持 // 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)); }
/** * The bean name of the internally managed Configuration annotation processor. */ publicstaticfinalStringCONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
/** * The bean name of the internally managed BeanNameGenerator for use when processing * {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext} * and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make * any custom name generation strategy available to the underlying * {@link ConfigurationClassPostProcessor}. * @since 3.1.1 */ publicstaticfinalStringCONFIGURATION_BEAN_NAME_GENERATOR= "org.springframework.context.annotation.internalConfigurationBeanNameGenerator";
/** * The bean name of the internally managed Autowired annotation processor. */ publicstaticfinalStringAUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
/** * The bean name of the internally managed common annotation processor. */ publicstaticfinalStringCOMMON_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalCommonAnnotationProcessor";
/** * The bean name of the internally managed JPA annotation processor. */ publicstaticfinalStringPERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
/** * The bean name of the internally managed @EventListener annotation processor. */ publicstaticfinalStringEVENT_LISTENER_PROCESSOR_BEAN_NAME= "org.springframework.context.event.internalEventListenerProcessor";
/** * The bean name of the internally managed EventListenerFactory. */ publicstaticfinalStringEVENT_LISTENER_FACTORY_BEAN_NAME= "org.springframework.context.event.internalEventListenerFactory";
publicAutowiredAnnotationBeanPostProcessor() { // Autowired this.autowiredAnnotationTypes.add(Autowired.class); // Value this.autowiredAnnotationTypes.add(Value.class);
try { // Inject // jakarta.inject.Inject this.autowiredAnnotationTypes.add((Class<? extendsAnnotation>) ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // jakarta.inject API not available - simply skip. }
try { this.autowiredAnnotationTypes.add((Class<? extendsAnnotation>) ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.trace("'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // javax.inject API not available - simply skip. } }
/** * Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>. * The returned bean object may be a proxy to use instead of the target bean, * effectively suppressing default instantiation of the target bean. * <p>If a non-null object is returned by this method, the bean creation process * will be short-circuited. The only further processing applied is the * {@link #postProcessAfterInitialization} callback from the configured * {@link BeanPostProcessor BeanPostProcessors}. * <p>This callback will be applied to bean definitions with their bean class, * as well as to factory-method definitions in which case the returned bean type * will be passed in here. * <p>Post-processors may implement the extended * {@link SmartInstantiationAwareBeanPostProcessor} interface in order * to predict the type of the bean object that they are going to return here. * <p>The default implementation returns {@code null}. * @param beanClass the class of the bean to be instantiated * @param beanName the name of the bean * @return the bean object to expose instead of a default instance of the target bean, * or {@code null} to proceed with default instantiation * @throws org.springframework.beans.BeansException in case of errors * @see #postProcessAfterInstantiation * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getBeanClass() * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName() */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)throws BeansException { returnnull; }
/** * Perform operations after the bean has been instantiated, via a constructor or factory method, * but before Spring property population (from explicit properties or autowiring) occurs. * <p>This is the ideal callback for performing custom field injection on the given bean * instance, right before Spring's autowiring kicks in. * <p>The default implementation returns {@code true}. * @param bean the bean instance created, with properties not having been set yet * @param beanName the name of the bean * @return {@code true} if properties should be set on the bean; {@code false} * if property population should be skipped. Normal implementations should return {@code true}. * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor * instances being invoked on this bean instance. * @throws org.springframework.beans.BeansException in case of errors * @see #postProcessBeforeInstantiation */ defaultbooleanpostProcessAfterInstantiation(Object bean, String beanName)throws BeansException { returntrue; }
/** * Post-process the given property values before the factory applies them * to the given bean. * <p>The default implementation returns the given {@code pvs} as-is. * @param pvs the property values that the factory is about to apply (never {@code null}) * @param bean the bean instance created, but whose properties have not yet been set * @param beanName the name of the bean * @return the actual property values to apply to the given bean (can be the passed-in * PropertyValues instance), or {@code null} to skip property population * @throws org.springframework.beans.BeansException in case of errors * @since 5.1 */ // 属性注入增强 @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
// 关闭三级缓存,并更改当前对象为 代理对象 if (earlySingletonExposure) { ObjectearlySingletonReference= getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } elseif (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = newLinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { thrownewBeanCurrentlyInCreationException(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."); } } } }
protectedvoidpopulateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { thrownewBeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } }
if (bw.getWrappedClass().isRecord()) { if (mbd.hasPropertyValues()) { thrownewBeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to a record"); } else { // Skip property population phase for records since they are immutable. 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 (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { // 实例化后 的 增强方法 // InstantiationAwareBeanPostProcessor ## postProcessAfterInstantiation if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } }