2023-09-16  阅读(1)
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/104970275

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定义:

202309162311139081.png

202309162311144342.png
后置处理器:

202309162311149543.png
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文