Spring源码剖析,spring源码分析

Spring源码剖析// Next, register the BeanPostProcessors that implement Ordered.
//接下来,注册实现 Ordered 的 BeanPostProcesso

//接下来,注册一个实现Ordered 的BeanPostProcessor。

//接下来,注册一个实现Ordered的BeanPostProcessor。

列出请求的后处理器=new ArrayList();

//处理实现有序的后处理器

for (String ppName : requestsPostProcessorNames) {

//获取后处理器bean

BeanPostProcessor pp=beanFactory.getBean(ppName, BeanPostProcessor.class);

//添加到收藏

orderPostProcessors.add(pp);

if (MergedBeanDefinitionPostProcessor 的pp 实例) {

内部后处理器.add(pp);

}

}

//排序后处理器

sortPostProcessors(ownedPostProcessors, beanFactory);

//初始化后注册

registerBeanPostProcessors(beanFactory, requestPostProcessors);

//在这里注册所有常规BeanPostProcessor。

//接下来,注册所有常规的BeanPostProcessor。

列表非OrderedPostProcessors=new ArrayList();

//

for (String ppName : nonOrderedPostProcessorNames) {

//获取bean实例

BeanPostProcessor pp=beanFactory.getBean(ppName, BeanPostProcessor.class);

nonOrderedPostProcessors.add(pp);

if (MergedBeanDefinitionPostProcessor 的pp 实例) {

内部后处理器.add(pp);

}

}

//注册一个常规的后处理器

registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

//最后,重新注册所有内部BeanPostProcessors。

sortPostProcessors(internalPostProcessors, beanFactory);

//最后,重新注册所有内部BeanPostProcessor。

registerBeanPostProcessors(beanFactory, externalPostProcessors);

//将后处理器重新注册为ApplicationListener 以发现内部bean。

//移动到处理器链的末尾(例如选择代理)。

//ApplicationListener检测器也是BeanPostProcessor

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

}

这里,根据类型BeanPostProcessor.class找到所有的后处理器,然后通过BeanFactory.getBean创建bean实例,并根据优先级注册到AbstractBeanFactory的ListBeanPostProcessor beanPostProcessors=new CopyOnWriteArrayList()集合中。报名顺序如下:下面继续:

注册实现PriorityOrdered 接口的最高优先级后处理器。

注册一个实现Ordered 接口的有序后处理器

注册一个常规的后处理器

注册内部使用的后处理器MergedBeanDefinitionPostProcessor

以AutowiredAnnotationBeanPostProcessor为例,它属于PriorityOrdered类别,我们首先看一下它的构造函数。

公共类AutowiredAnnotationBeanPostProcessor 扩展InstantiationAwareBeanPostProcessorAdapter

实现MergedBeanDefinitionPostProcessor、PriorityOrdered、BeanFactoryAware {;

…省略…

/**

创建一个新的AutowiredAnnotationBeanPostProcessor

对于Spring的标准{@link Autowired}注释。

如果可用,它还支持JSR-330 {@link javax.inject.Inject} 注释。

*/

//为Spring的标准Autowired注解创建一个新的AutowiredAnnotationBeanPostProcessor

@SuppressWarnings(“未选中”)

公共AutowiredAnnotationBeanPostProcessor() {

//添加注解类型进行注入

this.autowiredAnnotationTypes.add(Autowired.class);

this.autowiredAnnotationTypes.add(Value.class);

尝试{

//支持JSR-330 javax.inject.Inject注解

this.autowiredAnnotationTypes.add((类?扩展注释)

ClassUtils.forName(\”javax.inject.Inject\”, AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));

logger.info(“找到JSR-330 “javax.inject.Inject” 注释并支持自动装配”);

}

catch (ClassNotFoundException ex) {

//JSR-330 API 不可用- 请跳过。

}

}

可以看到它支持处理Autowired和Value注解,还支持JSR-330的javax.inject.Inject注解。下面是继承系统图:

财产注入

==================================================================

现在您知道AutowiredAnnotationBeanPostProcessor 何时实例化并向IOC 容器注册。接下来我们来分析一下AutowiredAnnotationBeanPostProcessor的工作流程。

上一篇文章我们分析了refresh()的IOC启动流程。

调用getFreshBeanFactory() 来加载、解析和注册bean。

通过调用registerBeanPostProcessors(beanFactory)注册后处理器。

通过调用this.finishBeanFactoryInitialization(beanFactory) 创建一个简单的bean。成功创建bean后,属性注入在AbstractAutowireCapableBeanFactory#populateBean中完成。

今天我们要学习的@Autowire注解的处理是在populateBean方法内完成的。

protected void PopulateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

//省略.

如果(hasInstAwareBpps){

//获取所有后处理器

for (BeanPostProcessor bp : getBeanPostProcessors()) {

//对于InstantiationAwareBeanPostProcessor类型

if (实例化AwareBeanPostProcessor 的bp 实例) {

InstantiationAwareBeanPostProcessor ibp=(InstantiationAwareBeanPostProcessor) bp;

//后处理器处理属性【这里调用AutowireAnnotationBeanPostProcess】

pvs=ibp.postProcessPropertyValues(pvs,filteredPds,bw.getWrappedInstance(),beanName);

如果(pvs==null){

返回;

}

}

}

}

处理自动接线

==========================================================================

下面是AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues源代码

@覆盖

公共PropertyValues postProcessPropertyValues(

PropertyValues pvs, PropertyDescriptor[] pds, 对象bean, 字符串beanName) throws BeanCreationException {

//搜索自动装配元数据,并根据bean的类使用反射检索bean的元注释信息。

InjectionMetadata 元数据=findAutowiringMetadata(beanName, bean.getClass(), pvs);

尝试{

//注射

元数据.注入(bean, beanName, pvs);

}

catch (BeanCreationException ex) {

扔掉原件。

}

catch(抛出的例子){

throw new BeanCreationException(beanName, “自动连线依赖注入失败”, ex);

}

返回pv。

}

这里,我们首先通过findAutowiringMetadata方法找到自动装配元注释信息InjectionMetadata,然后调用InjectionMetadata.inject执行注入。遵循findAutowiringMetadata 方法。

查找元注释

AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata的源码如下

private InjectionMetadata findAutowiringMetadata(String beanName, Class?clazz, @Nullable PropertyValues pvs) {

//回退到类名作为缓存键,以向后兼容自定义调用者。

//如果不使用类名作为名称,则获取bean的名称。

String queueKey=(StringUtils.hasLength(beanName) ? beanName : clazz.getName());

//从自动注入元数据缓存映射中查找InjectionMetadata

//首先以最少的锁定快速检查并发映射。

InjectionMetadata 元数据=this.injectionMetadataCache.get(cacheKey);

if (InjectionMetadata.needsRefresh(元数据, clazz)) {

已同步(this.injectionMetadataCache){

元数据=this.injectionMetadataCache.get(cacheKey);

if (InjectionMetadata.needsRefresh(元数据, clazz)) {

if(元数据!=null){

元数据.clear(pvs);

}

//构建自动程序集元数据并使用反射检索它

元数据=buildAutowiringMetadata(clazz);

//缓存自动装配元数据

this.injectionMetadataCache.put(cacheKey, 元数据);

}

}

}

返回元数据。

}

搜索元注释相对容易。如果缓存中没有,则调用buildAutowiringMetadata查找元注释信息并将其添加到缓存中。

私有InjectionMetadata buildAutowiringMetadata(final Class? clazz) {

LinkedListInjectionMetadata.InjectedElement 元素=new LinkedList();

类?目标类=clazz;

做{

最终LinkedListInjectionMetadata.InjectedElement currElements=new LinkedList();

ReflectionUtils.doWithLocalFields(targetClass, 字段- {

//查找@autowired注解的属性和注入对象

AnnotationAttributes ann=findAutowiredAnnotation(field);

if (ann !=null) {

if (Modifier.isStatic(field.getModifiers())) {

如果(logger.isWarnEnabled()){

logger.warn(\’静态字段不支持自动连线注释: \’ + field);

}

返回;

}

需要布尔值=需要决策状态(ann);

//添加到currElements集合

currElements.add(new AutowiredFieldElement(字段,必填));

}

});

.省略.

//将带注释的属性封装到injectionMetadata中。

返回一个新的InjectionMetadata(clazz, elements)。

}

使用反射根据bean类查找bean和注入的bean中的@Autowire注解信息,一一创建AutowiredFieldElements,封装在InjectionMetadata中并返回。该元素的结构如下:

财产注入

InjectionMetadata#inject 我们看一下注入方法

public voidject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

//获取要注入的属性集合

集合checkedElements=this.checkedElements;

迭代集合元素=

(checkedElements!=null ?checkedElements : this.injectedElements);

if (!elementsToIterate.isEmpty()) {

布尔调试=logger.isDebugEnabled();

for (InjectedElement 元素: elementsToIterate) {

如果(调试){

logger.debug(\”正在处理bean插入的元素\’\” + beanName + \’\’:\’ + element);

}

//调用InjectedElement的inject方法进行注入

element.inject(目标, beanName, pvs);

}

}

}

这里我们获取bean的依赖属性,InjectedElement集合,并通过调用inject一一注入值。代码为AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject。

@覆盖

protected voidject(Object Bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

字段字段=(字段) this.member;

对象的价值。

if (this.cached) {

值=solvedCachedArgument(beanName, this.cachedFieldValue);

}

除此之外{

//DependencyDescriptor 依赖描述符

依赖描述符描述=新的依赖描述符(field, this.required);

desc.setContainingClass(bean.getClass());

设置autowiredBeanNames=new LinkedHashSet(1)。

Assert.state(beanFactory !=null, “没有可用的BeanFactory”);

//类型转换器

TypeConverter typeConverter=beanFactory.getTypeConverter();

尝试{

//获取容器中的bean实例

value=beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

}

catch (BeansException ex) {

抛出新的UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);

}

Java面试核心知识点笔记

包括JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等等知识点。

Java中高级面试常见考点整理

最后,我将分享您需要的高级Java 学习和面试视频指导。

//获取容器中的bean实例

value=beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

}

catch (BeansException ex) {

抛出新的UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);

}

Java面试核心知识点笔记

包括JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等等知识点。

[正在传输外部链接图像.(img-asKNO22R-1719175758994)]

Java中高级面试常见考点整理

[外部链接图像正在传输.(img-pz1M8JwR-1719175758995)]

[外部链接图像正在传输.(img-4IRJW8YP-1719175758996)]

最后,我将分享您需要的高级Java 学习和面试视频指导。

[外部链接图像正在传输.(img-Z5WSmp5e-1719175758996)]

以上关于#Spring源码分析的相关内容摘自网络,仅供参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91881.html

(0)
CSDN的头像CSDN
上一篇 2024年6月24日
下一篇 2024年6月24日

相关推荐

  • tsn协议应用(tsn 协议)

    来源:网络技术联盟站  你好,这里是网络技术联盟站。 TSN,全名为Time-Sensitive Networking,是一项关键的网络技术,旨在实现在以太网网络中的实时…

  • 智能访客管理系统

    随着企业规模的不断扩大和访客流量的增加,传统的访客管理方式已难以满足现代企业的需求。纸质登记、人工审核等方式不仅效率低下,而且存在信息易丢失、难以追溯等问题。因

    2024年9月22日
    0
  • 编程中的cow是什么

    编程中的COW是Copy On Write的缩写,是一种用于减少数据复制操作带来的性能开销的优化策略。 COW技术主要保证系统在复制数据时,不会立即创建物理副本,而是让数据副本共享…

    网站运维 2024年5月12日
    0
  • SQL基础语句学习

    sql对大小写不敏感可以把sql分为两部分:数据操作语言(DML)和数据定义语言(DDL)查询和更新指令构成了SQL的DML部分:select-从数据库表中获取

    2024年9月1日
    0

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注