Spring 5.x 源码之旅三BeanDefinition实现与ClassPathBeanDefinitionScanner

AbstractBeanDefinition抽象实现

我们继续上一篇的bean定义说明。
在这里插入图片描述
其实就是继承了上面的bean元数据访问器并且实现了bean定义接口,这样的话就可以让bean的元数据和bean的定义接口联系起来了,也就是数据和操作结合了。这个类比较长,我不打算从头到位贴上来,说几个要注意的地方:

	//this.beanClasss是对象,可以是String也可以是Class
	@Override
	@Nullable
	public String getBeanClassName() {
		Object beanClassObject = this.beanClass;
		if (beanClassObject instanceof Class) {
			return ((Class<?>) beanClassObject).getName();
		}
		else {
			return (String) beanClassObject;
		}
	}
	
	//可以传Class
	public void setBeanClass(@Nullable Class<?> beanClass) {
		this.beanClass = beanClass;
	}
	//判断beanClass是否是个Class对象
	public boolean hasBeanClass() {
		return (this.beanClass instanceof Class);
	}

	//定义了一个克隆的抽象方法
	public abstract AbstractBeanDefinition cloneBeanDefinition();

GenericBeanDefinition标准的bean定义

在这里插入图片描述
增加了一个父类名字,实现了抽象克隆方法:

	@Nullable
	private String parentName;

	@Override
	public AbstractBeanDefinition cloneBeanDefinition() {
		return new GenericBeanDefinition(this);
	}

AnnotatedBeanDefinition注解bean定义

在这里插入图片描述
加了两个新方法,其实就是注解的元数据和工厂方法的元数据,这些数据在进行解析处理的时候需要用到。

public interface AnnotatedBeanDefinition extends BeanDefinition {

	
	AnnotationMetadata getMetadata();

	
	@Nullable
	MethodMetadata getFactoryMethodMetadata();

}

AnnotatedGenericBeanDefinition注解通用bean定义

在这里插入图片描述
别看他的继承如图那么复杂,其实就是上面讲的这些,就是将通用bean定义GenericBeanDefinition和注解bean定义AnnotatedBeanDefinition拼起来了。

public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
	//注解元数据
	private final AnnotationMetadata metadata;
	//工厂方法源数据
	@Nullable
	private MethodMetadata factoryMethodMetadata;


	//通过beanClass来获取元数据
	public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
		setBeanClass(beanClass);
		this.metadata = AnnotationMetadata.introspect(beanClass);
	}

	//通过注解元数据来获取beanClass
	public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
		Assert.notNull(metadata, "AnnotationMetadata must not be null");
		if (metadata instanceof StandardAnnotationMetadata) {
			setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
		}
		else {
			setBeanClassName(metadata.getClassName());
		}
		this.metadata = metadata;
	}

	//通过注解元数据和方法元数据创建
	public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) {
		this(metadata);
		Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null");
		setFactoryMethodName(factoryMethodMetadata.getMethodName());
		this.factoryMethodMetadata = factoryMethodMetadata;
	}


	@Override
	public final AnnotationMetadata getMetadata() {
		return this.metadata;
	}

	@Override
	@Nullable
	public final MethodMetadata getFactoryMethodMetadata() {
		return this.factoryMethodMetadata;
	}

}

RootBeanDefinition合并bean定义

在这里插入图片描述
这个主要是将很多其他类型的BeanDefinition在运行时合并起来,具体的用法后面会说,现在只要知道基本内部的定义都是用这个的。

ClassPathBeanDefinitionScanner扫描类定义

这个就是来扫描我们注解,比如@Component,@Repository,@Service,@Controller,或者java扩展的javax.annotation.ManagedBeanjavax.inject.Named,当然创建的时候他没有干什么事,只是做了一些基本的配置,比如注册过滤器,比如能过滤@Component注解,然后设置ResourceLoader,创建元数据缓存CachingMetadataReaderFactory等。

	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;
		//是否使用默认过滤器
		if (useDefaultFilters) {
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

registerDefaultFilters注册默认过滤器

主要是@Component,但是还有其他的一些java扩展的。

protected void registerDefaultFilters() {
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

setResourceLoader设置资源加载器

这里创建了ResourcePatternResolver,用来解析URL资源,创建了CachingMetadataReaderFactory,用来做字节码文件元数据的缓存,创建了CandidateComponentsIndexspring内部定义的组件,在META-INF/spring.components里,貌似现在还没用到。

	@Override
	public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
		this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
		this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
		this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
	}

至此AnnotationConfigApplicationContext创建完成了,主要创建了读取器和扫描器,读取器里面又注册了注解后置处理器的bean定义,特别是这个ConfigurationClassPostProcessor,后面马上会用到他,他就是来解析我们配置类的。而扫描器不是他内部用的,是给我们用户用的,内部他要用还会创建一个。我们后面就继续看他怎么处理我们的配置类。

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识。   第2章:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。   第3章:讲解Spring IoC容器的知识,通过具体的实例详细地讲解IoC概念。同时,对Spring框架的三个最重要的框架级接口进行了剖析,并对Bean的生命周期进行讲解。   第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。   第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们还将对Spring容器一些高级主题进行深入的阐述。   第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。   第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。   第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。   第9章:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。   第10章:对实际应用中Spring事务管理各种疑难问题进行透彻的剖析,让读者对Spring事务管理不再有云遮雾罩的感觉。   第11章:讲解了如何使用Spring JDBC进行数据访问操作,我们还重点讲述了LOB字段处理、主键产生和获取等难点知识。   第12章:讲解了如何在Spring中集成Hibernate、myBatis等数据访问框架,同时,读者还将学习到ORM框架的混用和DAO层设计的知识。   第13章:本章重点对在Spring中如何使用Quartz进行任务调度进行了讲解,同时还涉及了使用JDK Timer和JDK 5.0执行器的知识。   第14章:介绍Spring 3.0新增的OXM模块,同时对XML技术进行了整体的了解。   第15章:对Spring MVC框架进行详细介绍,对REST风格编程方式进行重点讲解,同时还对Spring 3.0的校验和格式化框架如果和Spring MVC整合进行讲解。   第16章:有别于一般书籍的单元测试内容,本书以当前最具实战的JUnit4+Unitils+ Mockito复合测试框架对如何测试数据库、Web的应用进行了深入的讲解。   第17章:以一个实际的项目为蓝本,带领读者从项目需求分析、项目设计、代码开发、单元测试直到应用部署经历整个实际项目的整体开发过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值