Spring 5.x 源码之旅-4AnnotatedBeanDefinitionReader注册配置类与刷新

本文介绍了深入Java技术的学习路径,包括多线程、设计模式、JUC源码、JDK和JVM源码,以及Spring框架中的BeanDefinitionReader处理配置类和后置处理器的详细过程。着重展示了如何解析配置类,将其转换为BeanDefinition并注册到BeanFactory中,以及后置处理器在BeanFactory初始化中的关键作用。
摘要由CSDN通过智能技术生成

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

register(componentClasses)注册配置类

前面我们讲了注解读取器和类扫描器创建完成了,接下来就是进行我们传入的配置类解析,其实配置类可以传多个,因为参数是一个可变长数组:

    	@Override
    	public void register(Class<?>... componentClasses) {
    		Assert.notEmpty(componentClasses, "At least one component class must be specified");
    		this.reader.register(componentClasses);
    	}

AnnotatedBeanDefinitionReader的register(componentClasses)

    	public void register(Class<?>... componentClasses) {
    		for (Class<?> componentClass : componentClasses) {
    			registerBean(componentClass);
    		}
    	}
    
    	public void registerBean(Class<?> beanClass) {
    		doRegisterBean(beanClass, null, null, null, null);
    	}

AnnotatedBeanDefinitionReader的doRegisterBean注册配置类

这里是完成了一个配置类的注册。首先根据配置类创建一个注解通用bean定义AnnotatedGenericBeanDefinition ,然后进行条件判断,从bean定义解析范围,并设置范围,然后获得bean的名字,处理通用注解,比如@Lazy@Primary@DependsOn等。如果有自定义BeanDefinitionCustomizer的话,就会进行回调。最后将bean名字和bean定义封装成BeanDefinitionHolder,方便处理,同时会根据注解的代理信息看是否要进行代理,最后注册到注册器里。

    private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
    			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
    			@Nullable BeanDefinitionCustomizer[] customizers) {
    
    		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);//封装成注解bean定义
    		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {//是否满足条件
    			return;
    		}
    
    		abd.setInstanceSupplier(supplier);//设置bean创建的回调
    		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//解析范围元数据
    		abd.setScope(scopeMetadata.getScopeName());//设置范围
    		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//获取bean名字
    		//处理通用注解Lazy Primary DependsOn Role Description
    		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    		if (qualifiers != null) {
    			for (Class<? extends Annotation> qualifier : qualifiers) {
    				if (Primary.class == qualifier) {
    					abd.setPrimary(true);
    				}
    				else if (Lazy.class == qualifier) {
    					abd.setLazyInit(true);
    				}
    				else {
    					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
    				}
    			}
    		}
    		if (customizers != null) {//对bean定义可以自定义一些操作
    			for (BeanDefinitionCustomizer customizer : customizers) {
    				customizer.customize(abd);
    			}
    		}
    		//封装成BeanDefinitionHolder
    		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//可能要返回代理
    		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);//注册
    	}

这里的一些方法展开暂时不讲,因为涉及很多细节,现在能知道这个做了点什么就可以了,主要知道他创建了一个AnnotatedGenericBeanDefinition把配置类的注解都获取到了,然后放进bean定义中,最后将bean定义注册到注册器里。

refresh刷新

这个才是重要的地方,我们一个个方法来分析下,重点的会将细节,不是重点的就大致说下干嘛用的。

prepareRefresh预处理

设置一些参数和监听器。

    protected void prepareRefresh() {
    		// Switch to active.
    		this.startupDate = System.currentTimeMillis();
    		this.closed.set(false);
    		this.active.set(true);
    
    		if (logger.isDebugEnabled()) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Refreshing " + this);
    			}
    			else {
    				logger.debug("Refreshing " + getDisplayName());
    			}
    		}
    
    
    		initPropertySources();
    
    		getEnvironment().validateRequiredProperties();
    
    		// Store pre-refresh ApplicationListeners...
    		if (this.earlyApplicationListeners == null) {
    			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    		}
    		else {
    			
    			this.applicationListeners.clear();
    			this.applicationListeners.addAll(this.earlyApplicationListeners);
    		}
    
    
    		this.earlyApplicationEvents = new LinkedHashSet<>();
    	}

obtainFreshBeanFactory获得BeanFactory

进行刷新标志的设置,然后返回DefaultListableBeanFactory对象。

    	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    		refreshBeanFactory();
    		return getBeanFactory();
    	}

refreshBeanFactory

原子操作,支持单线程刷新,设置一个序列化ID

    @Override
    	protected final void refreshBeanFactory() throws IllegalStateException {
    		if (!this.refreshed.compareAndSet(false, true)) {
    			throw new IllegalStateException(
    					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
    		}
    		this.beanFactory.setSerializationId(getId());
    	}

prepareBeanFactory预处理BeanFactory

BeanFactory进行预处理,比如设置加载器,表达式解释器,添加BeanPostProcessor后置处理器ApplicationContextAwareProcessor,此时才是第一个后置处理器,然后忽略一些接口,然后是一些依赖对象设置,然后又添加了ApplicationListenerDetector后置处理器。 最后注册一些单例 ,比如环境,系统属性啊。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory 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.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);
    
    		// 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)) {
    			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());
    		}
    	}

invokeBeanFactoryPostProcessors调用BeanFactory后置处理器

这个是关键,开始要执行后置处理器,来处理我们的bean定义了。

    	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
    
    		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    		}
    	}

主要是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());里面涉及到很多东西,开始解析我们bean定义,生成相应的处理器进行处理,这个我们后面一篇说吧。我们现在知道了注册配置类,仅仅是对配置类做一些注解的解析,然后封装成bean定义放入注册器里。
看看此时我们的beanFactory里面的bean定义:


后置处理器:


 

  • 32
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值