前面我们通过解析配置文件元素的方式加载了BeanDefinition,但是spring野心不止于此,她呼应市场需求,开始慢慢的向注解配置的方向走去,于是乎出现了如今微服务化的spring-boot,那么spring是怎么通过注解配置来解析BeanDefinition的呢?
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = 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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(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();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
。。。。。。省略部分代码
}
}
上面的refresh()方法,我们已经分析过prepareRefresh()和obtainFreshBeanFactory()方法,prepareRefresh()用于初始化资源使用,子类可以覆写上面的方法,obtainFreshBeanFactory()用于刷新容器,获取Beanfactory并解析xml配置,那么接下来我们来研究prepareBeanFactory方法
protected void org.springframework.context.support.AbstractApplicationContext.prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//设置spring表达式解析器,用于解析表达式
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//添加注册员,具有将属性编辑器注册到注册处(PropertyEditorRegistry)的能力
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//配置ApplicationContextAwareProcessor后置处理器,这个处理器
//实现了BeanPostProcessor接口,我们的bean如果实现了ApplicationContextAware接口
//那么会在bean初始化前设置ApplicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//添加忽略的接口,由ApplicationContextAwareProcessor后置处理器设置
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
//添加忽略的接口,由ApplicationContextAwareProcessor后置处理器设置
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
//添加忽略的接口,由ApplicationContextAwareProcessor后置处理器设置
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//添加忽略的接口,由ApplicationContextAwareProcessor后置处理器设置,为什么要忽略这些接口的依赖?因为这些依赖都是spring内部创建,没有纳入BeanFactory中,不归BeanFactory管
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//注册用于自动装配使用的对象,这些东西没有注册到BeanFactory中,
//所以这里通过BeanFactory的resolvableDependencies(Class-->实例对象)注册
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//如果存在LoadTimeWeaver,那么设置类加载编织器,这种方式主要通过实现特殊的类加载器将我们的切面编织进去然后加载到JVM中
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
//设置临时加载器,这个加载就是那个特殊的类加载,符合代理条件的class将会由这个加载(实际上还是用的父加载器,加载完后对类的字节码做了一些更改后返回)
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
//将环境变量直接注册到单例bean集合中
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());
}
}
总结一下prepareBeanFactory这个方法,这个方法主要是注册了一些在属性填充时进行忽略接口依赖和一些额外的用于自动装配的依赖,还设置了spring的动态表达式解析器,属性编辑器(用于处理属性类型的转换),注册了环境实例到单例工厂中,添加了ApplicationContextAware,如果存在运行时编织器,那么还会设置用于aop的类特殊临时加载器。下面我们继续postProcessBeanFactory方法,这个方法在调用完postProcessBeanFactory方法后执行
protected void org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//用于处理ServletContextAware接口,在初始化前设置ServletContext和ServletConfig
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
//因为使用了后置处理器,并且ServletContext不会归管与普通的BeanFactory,所以忽略
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
//注册扩展的web应用scope,比如request,session,globalSession,application,注册额外用于依赖注入的request,session,jsf等,这些类使用ObjectFactory对应实现类来封装,比如RequestObjectFactory
//像我们如果需要使用request的时候我们就可以在类中@Autowire HttpSerlvetRequest request
//https://www.primefaces.org/ --》一个实现了jsf标签的官网
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
//这里面主要是注入单例bean,ServletContext,ServletConfig,
//ServletContext和ServletConfig的初始化参数以map的方式注入
//servletContext的属性值
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
postProcessBeanFactory方法主要是添加扩展的scope,和注入与web相关的依赖。值得注意的是,这里注入的单例bean要么是tomcat创建的,要么就是自己创建的,他们除了是单例之外有一个共同点,那就是没有对应的BeanDefinition,所以想这样的单例bean会有一个专门的集合来保存他们的beanName,那就是manualSingletonNames集合,这个集合我们最早在BeanDefinition注册的时候见到过。 postProcessBeanFactory方法看完了,我们继续分析invokeBeanFactoryPostProcessors方法,这是refresh方法中的第五个方法了。这个方法内部直接调用了一个静态方法。PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors,从方法名可以看出这个方法是调用BeanFactory后置处理器的。
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
//如果BeanFactory是实现了BeanDefinitionRegistry接口的,那么才有
//BeanDefinition注册后置处理
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//只是实现了BeanFactoryPostProcessor的放这
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
//实现了BeanDefinitionRegistryPostProcessor的放置在这,BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//目前版本的spring4.2.6默认情况下beanFactoryPostProcessors集合是没有数据的,不过我们可以通过实现ApplicationContextInitializer来设置自定义的BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//实现了BeanDefinitionRegistryPostProcessor的会立马调用
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
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.
//获取BeanDefinitionRegistryPostProcessor类型的BeanDefinition名,这里第二参数表示是否允许包含非单例bean,第三个参数
//为false表示不允许提前初始化FactoryBean,如果提前初始化,后置处理器没法使用到他们,这里获取对应bean的beanName将已单独小节来分析
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//首先排序并处理时限了优先排序接口的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
//判断是否为PriorityOrdered接口实现,不要小看isTypeMatch方法,这个方法也挺复杂的,这个方法将与beanFactory.getBeanNamesForType一次分析
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序,这个排序比较器在我们解析@Component中设置过,首先通过优先级来排序,再者通过order接口排序,如果方法,是类等会还会以@Order排序,@priority排序
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
//调用方法
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//再次获取BeanDefinitionRegistryPostProcessor,因为上面已经调用过一次BeanDefinitionRegistryPostProcessor,可能已经注册了了新的postProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
//处理实现了order接口的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
//最后循环调用,直至没有添加新的BeanDefinitionRegistryPostProcessor为止
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,所以需要调用postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
//调用直接实现BeanFactoryPostProcessor接口的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
//如果当前的BeanFactory不是BeanDefinitionRegistry,直接调用postProcessBeanFactory
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!
//获取BeanFactoryPostProcessor的实现类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
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...
//清除合并BeanDefinition数据,因为此时后置处理器可能会修改BeanDefinition
beanFactory.clearMetadataCache();
}
上面的代码处理了BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor,他们的处理方式类似,不同的是BeanDefinitionRegistryPostProcessor只从BeanFactory获取了一次,BeanDefinitionRegistryPostProcessor每次调用之后都要重新从BeanFactory获取。 BeanDefinitionRegistryPostProcessor是spring提供修改BeanDefinition,或者添加BeanDefinition的处理器,BeanFactoryPostProcessor是所有BeanDefinition加载完毕后进行的处理,可以进行修改,添加BeanDefinition,但是不会再处理新添加的BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor,接下来就是我们要重点关注的注解配置后置处理器ConfigurationClassPostProcessor
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//引入后置处理器,设置注解元数据,通常用来检测某个类是否标注有对应的注解,没有就报错,以当前bean的父类作为key,获取引入注解元数据
RootBeanDefinition iabpp = new RootBeanDefinition(ImportAwareBeanPostProcessor.class);
iabpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(IMPORT_AWARE_PROCESSOR_BEAN_NAME, iabpp);
//设置增强配置后置处理,目前从代码中看到它只是在应用属性值前对对应的bean设置了BeanFactory实例。
RootBeanDefinition ecbpp = new RootBeanDefinition(EnhancedConfigurationBeanPostProcessor.class);
ecbpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME, ecbpp);
int registryId = System.identityHashCode(registry);
//表示BeanDefinition的后置处理是否已经调用过了
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);
}
//表示BeanDefinition注册后置处理已经处理
this.registriesPostProcessed.add(registryId);
//处理配置BeanDefinition
processConfigBeanDefinitions(registry);
}
上面配置了一些引入,增强配置后置处理,接下来就是进行配置bean定义的处理了
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
//获取bean定义的beanName,如果已经冻结配置,那么获取冻结集合的beande,否则获取beanDefinitionNames集合的beanName
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断当前BeanDefinition是否为完整配置(被@Configuration注解的)
//或者是精简配置(@Component,@ComponentScan,@Bean,@Import@ImportResource)
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//检测当前BeanDefinition是否有@Configuration,有就给当前BeanDefinition设置完全匹配的属性,就是上一步判断使用的属性,
//其他的就是精简配置
//如果还有@Order注解,那么也会在BeanDefinition中设置属性表示这个BeanDefinition在注解配置中的顺序
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//添加候选的BeanDefinition,这里可能会有疑问哈,前面不是已经注册了@Component注释的bean吗,为啥现在又添加进来了,这个还是往下看寻找答案吧。
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
//排序,如果没有配置@Order,那么优先级最低
Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
@Override
public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry singletonRegistry = null;
//如果当前BeanFactory实现与单例bean注册器,那么说明拥有单例bean直接注册的能力
if (registry instanceof SingletonBeanRegistry) {
singletonRegistry = (SingletonBeanRegistry) registry;
//如果没有设置beanName生成器,查看BeanFactory中是否已经设置了,如果没有的话,就使用默认的注解beanName生成器
//这个生成器我们在分析@Component注解扫描的时候分析过,此处不再赘述
if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
// Parse each @Configuration class
// @Configuration解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
//解析
parser.parse(candidates);
//校验每个候选的class,候选的class不能是final的,因为cglib代理是不能继承被final修饰的类
//静态的方法会直接被返回,如果这个@Bean是在被@Configuration
//标注的类中,那么这个方法不能是静态的,不能是final的,也不能是private,因为它的类需要被cglib代理
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<String>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
具体解析配置文件的过程
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
//查看类上是否有@Conditional注解,如果有,获取Condition进行匹配
//这里在上一节分析@Component扫描的时候分析过,不再赘述
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
//判断importedBy集合不为空,就说明这个配置类是被其他的配置类引入的
//如果当前的class由其他class引入,并且已经存在也是被其他的导入的,那么合并,更新主动引用自己的对象
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.
//如果当前class不是被引入的,并且已经有相同的class被引入了,那么以主动为准,因为后面会对主动引入类进行跳过判断
//如果一个被引入类的主类都是被跳过的,那么这个被引入类也会被跳过,所以如果已经由被动变为主动
//那么它就应当享有主动权
this.configurationClasses.remove(configClass);
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) {
if (configClass.equals(it.next())) {
it.remove();
}
}
}
}
// Recursively process the configuration class and its superclass hierarchy.
//包装成SourceClass
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
当前方法还是没有进入正题,还在做些准备工作,当我们看到do开头的doProcessConfigurationClass方法的时候,那么这就是spring真正开始工作的地方了
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// Recursively process any member (nested) classes first
//(1)首先解析成员或嵌入的@Configuration类
processMemberClasses(configClass, sourceClass);
// Process any @PropertySource annotations
//解析@PropertySource,@PropertySources,获取他们的属性
//我们可以使用这些注解声明我们的properties文件地址
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
//如果是可配置的环境,那么具有动态配置属性资源的能力
if (this.environment instanceof ConfigurableEnvironment) {
//处理从注解中获取到的属性资源地址,使用PropertiesLoaderUtils加载properties文件,包装成ResourcePropertySource实例,添加到Environment中,如果名字发生冲突的会以组合模式的方式构建CompositePropertySource添加进去
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
//处理@ComponentScan注解,获取其所有属性(包括被覆写的)
AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class);
//这里的conditionEvaluator处理@Conditional注解的方式阶段和前面看到的不一样
//前面是配置阶段,现在是注册bean阶段,也就是说如果你的实现condition是ConfigurationCondition,设置的阶段必须是ConfigurationPhase.REGISTER_BEAN
//才能被加载
if (componentScan != null && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
//ComponentScanAnnotationParser这个解析器与自定义标签component-scan对应的ComponentScanBeanDefinitionParser
//其实是差不多的,只不过是换成了从注解属性中获取TypeFilter,
//basePackage,resourcePattern,只是多了那个一个basePackageclasses
//而这个属性只不过是告诉你我要以这个类的包名作为基包路径
//内部用于扫描类的扫描器都是一样的,都是ClassPathBeanDefinitionScanner,所以不再赘述
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 necessary
//检查扫描的BeanDefinition是否也是@Configuration或者是精简配置,是的话,进行递归配置
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
}
}
}
// Process any @Import annotations
//处理引入配置@Import({"com.zhipin.AopConfiguration"})
//getImports(sourceClass)会从下往上递归查找@Import注解,并将@Import注解配置的class都转换成SourceClass
//(2)processImports
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
//解析@ImportResource注解,这个注解配置的是spring的xml配置
//xml配置的解析其实是和我们注解配置的xml配置的解析是一样的
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
//获取配置文件地址
String[] resources = importResource.getAliasedStringArray("locations", ImportResource.class, sourceClass);
//解析对应配置文件的读取器,我们在前面介绍过,默认是XmlBeanDeReader,但是如果这里没有指定的话,默认是一个BeanDefinitionReader接口,那spring会使用哪个实现类呢?不妨猜猜
//具体是什么往后看就知道了
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
//importedResources 资源地址--》对应的BeanDefinitionReader的Class对象
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
//处理@Bean注解,获取标注有@Bean的方法
Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata methodMetadata : beanMethods) {
//存入当前ConfigurationClass的beanMethods集合中
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
//处理接口中的default方法(JDK8以后接口中可以定义default方法)
//解析@Bean
for (SourceClass ifc : sourceClass.getInterfaces()) {
beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
}
// Process superclass, if any
//如果有父类,那么处理父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
//(1)解析成员(嵌套@Configuration类)
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
//获取其成员类
for (SourceClass memberClass : sourceClass.getMemberClasses()) {
//判断是否有@Configuration和精简配置注解
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
//检查是否重复引入配置类
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//递归处理配置类,memberClass被转换为ConfigurationClass,引入它的ConfigurationClass是configClass processConfigurationClass(memberClass.asConfigClass(configClass));
}
finally {
this.importStack.pop();
}
}
}
}
}
//(2)处理引入类
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {
if (importCandidates.isEmpty()) {
return;
}
//判断是否循环引入
if (checkForCircularImports && this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
//判断当前引入的类是否是引入选择器的子类
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
//判断是否为EnvironmentAware等Aware,会进行设置
invokeAwareMethods(selector);
//判断是否是延迟引入选择器,延迟选择器会在被放在最后解析
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
//使用选择器选择需要加载的配置类名,比如spring中有AsyncConfigurationSelector的实现,通过@EnableAsync指定使用什么样的配置
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
//递归处理
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
//添加引入的BeanDefinition注册者,我们可以通过这种方式实现自定BeanDefinition的注册 configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
//注册到一个多值map中,这个ImportStack实现了ImportRegistry接口
/**
* public void registerImport(AnnotationMetadata * importingClass, String importedClass) {
//被引入类的类名做为可以,主动引入它的作为value
* this.imports.add(importedClass, importingClass);
*
* }
*/
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//递归解析 processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Exception ex) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
处理完候选的class之后就处理延迟选择器中的内容,处理的方法是这个 processDeferredImportSelectors(); 方法和立刻引入的方法是一样的操作,不再赘述。
一切准备就绪,下面开始BeanDefinition的加载,这里是org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)中一段代码片段,完整的代码我们在上面已经贴过了。
//候选的BeanDefinition集合
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
//保存已经解析过的类
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
//解析bean,获取到它与父类,引入的,扫描的bean
parser.parse(candidates);
//检验如果是@Configuration的class不能是final的,其内部被@Bean的方法必须是可覆写
parser.validate();
//获取所有的待配置的类
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
//移除已经解析过的class
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
//构建BeanDefinition读取器你,和读取xml配置文件一样的套路
//都要建立一个bean定义读取器
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//加载BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
//清空旧的BeanDefinition
candidates.clear();
//如果注册的BeanDefinition比原来多了,那么说明已经注入了新的BeanDefinition
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取最新的beanName
String[] newCandidateNames = registry.getBeanDefinitionNames();
//获取老的BeanDefinition
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<String>();
//将已经解析的,也就是最新注入的类名取出
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
//如果老的不包含,那么说明这是一个新加的BeanDefinition
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
//如果这个BeanDefinition不属于刚才新解析出来的BeanDefinition,那么说明引入了实现了ImportBeanDefinitionRegistrar接口的类,这个接口运行你添加新的BeanDefinition到BeanFactory中
//并且这个BeanDefinition也是一个配置类,那么就需要对这个新加的BeanDefinition进行解析
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
//加入候选BeanDefinition集合,进行解析
candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
}
}
}
//更新集合,继续下次是否新增BeanDefinition判断
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
//注册单例bean,用于支持实现了ImportAware接口的类使用
if (singletonRegistry != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
当配置的类准备就绪之后,那么就可以使用配置类读取器开始bean定义的读取了,在分析读取逻辑之前,我们先大致过一下关系类图和序列图
- ConfigurationClassPostProcessor(在解析compon-scan标签时注入的一个后置处理器)
- ConfigurationClassParser(配置类解析器,筛选出符合条件的配置类)
- ConfigurationClass(用于保存解析的配置类信息)
- ComponentScanAnnotationParser(注解解析器,用于解析@ComponentScan注解)
- ConditionEvaluator(条件执行器,用于执行@Conditional指定的Condition实现类)
- ConditionContextImpl(条件上下文,提供条件执行器所需的数据)
- ConfigurationClassBeanDefinitionReader(配置类bean定义读取器)
从BeanFactory中获取工厂bean和bean定义后置处理器,并调用他们,其中我们的ConfigurationClassPostProcess后置处理器是在解析自定义标签component-scan时加入的,ConfigurationClassPostProcess将bean工厂中已经存在的BeanDefinition全部取出,并对他们自己,父类,引入类,扫描包进行配置注解判断,符合条件的bean定义被解析成ConfigurationClass存到集合中,等待ConfigurationBeanDefinitionReader进行读取
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?