spring源码解读-第二部分面想切面编程

Spring源码解读 Spring Framework源码地址:https://github.com/spring-projects/spring-framework 从目录结构可以看出整个Spring框架都遵从模块化设计的思路,总共分为20多个模块,如下图所示: 从上图可以看出: Spring主要分为五个部分: 1、测试模块:主要实现了Spring的Junit等测试框架。 2、Spring核心容器:里面... 阅读详情

这是第二部分了。看这部分源码需要第一部分基础。但是不知道也没关系。spring在代码耦合上控制的很好。

先进行知识扫盲:
JoinPoint :
大白话:就是你的bean里面的方法;一个类里面有多少个方法(公共的)就有多少个JoinPoint,只是一个定义,方便进行表达沟通。比如说人家问你JoinPoint是什么,你就说:是xxx类的xx方法;
专业解释:系统中的执行点。不同的规范中可能有不同类型的执行点(方法调用,方法执行,构造器,属性赋值等等,不要记费神);Spring中只支持方法执行级别的执行点;
切面:
Pointcut:切入点,用这个就是定义了一个或者一批joinPoint。然后可以通过织入的动作把增强逻辑加入到这些执行点上面;
Advice:增强逻辑,就是一段你写的代码;然后分为前置增强,后置增强,环绕增强;
Aspect:切面,Pointcut和Advice共同组成切面。
通知、增强处理(Advice) 就是你想要的功能,也就是上说的安全、事物、日子等。你给先定义好,然后再想用的地方用一下。包含Aspect的一段处理代码
Weaving:织入,代表一个操作,就是把切面加到切点上,生成一个带有切面逻辑的代理的操作;

动态代理和CGLIB(作者发现spring在源码中已经包含了cglib代码在org.springframework.cglib中,所以不需要再单独引入了)代理的知识你自己查查呗。知道代理模式和如何使用就可以了。

下面说说思想然后再去看源码;
spring织入aop逻辑可以通过手动编码,配置文件,注解等多种方式。

还记得第一部分,spring在出现循环依赖的时候,需要对bean进行提前代理。那么我们就先去看这部分代码;
路标1: getEarlyBeanReference;
看过第一部分的源码解析之后,你应该能在半分钟内找到下面的代码。不然说明你还需要努力;
我们看到这里是通过接口SmartInstantiationAwareBeanPostProcessor来实现来对bean进行加工的。那么这个BeanPostProcessor是在啥时候注册的呢?这个问题留给你去探索一下。其实这个问题应该在第一部分就讲解的;但是留给你探索有助于你加深印象。

	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
					if (exposedObject == null) {
						return exposedObject;
					}
				}
			}
		}
		return exposedObject;
	}

路标2:ibp.getEarlyBeanReference(exposedObject, beanName)

	@Override
	public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		//取一个缓存用的key:beanClass.getName() + "_" + beanName
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		this.earlyProxyReferences.add(cacheKey);
		return wrapIfNecessary(bean, beanName, cacheKey);
	}

路标3:wrapIfNecessary(bean, beanName, cacheKey)

	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.获取这个bean命中的切面列表
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

路标4:createProxy
这里就是给bean创建代理的地方了,会根据你配置的切面信息进行织入,然后返回一个完成的代理对象

	protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	} 

这是提前代理的地方,那么正常生命周期的bean在哪里代理呢?先告诉你答案,肯定是在实例化完成之后。那么我们是去找初始化那部分代码。半分钟内能找到吗?

路标doCreateBean->initializeBean ->applyBeanPostProcessorsAfterInitialization;
就在这里的时候进行处理的;你可能说这里也看不出来啥啊?是的。但是别忘了上面那种情况就是beanPostProcess来干活的。那么那个postProcess这里是不是也可以取到,先告诉你一个实现,剩下的你自己研究下AnnotationAwareAspectJAutoProxyCreator

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}

看下AnnotationAwareAspectJAutoProxyCreator中的逻辑

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			//判断是否有早期暴露
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

上面问题的提醒:refresh()->registerBeanPostProcessors();但是这里并没有找到相关信息。却可以看到这里有通过容器去加载BeanPostProcessors对应的bean.那么你可以想一下。各种开启aop的方式,从那里找找看能不能找到什么线索!

阿里从业七年经验架构师对Spring源码深度解读(附带源码视频) 阅读源码的重要性 Java开发人员都知道,阅读源码是非常好的学习方式,在我们日常工作中或多或少都会接触一些开源代码, 比如说最常用的Struts、Hibernate、 Spring, 这些源码的普及与应用程度远远超过我们的想象,正因为很多人使用,也在推动着源码不断地完善。这些优秀的源码中有着多年积淀下来的精华,这些精华是非常值得我们学习的,不管我们当前是什么水平,通过反复阅读源码,能力都会有所提升,小到对源码所提供的功能上的使用更加熟练,大到使我们的程序设计更加完美优秀。但是,纵观我们身边的人,能够做到通 阅读详情

相关推荐

给新人的储能系统入门图解:从电芯到EMS,一张图看懂BESS里那些‘黑话’

本文通过视觉化拆解储能系统,从电芯到EMS详细解析BESS中的关键组件和行业术语。涵盖电芯参数、模组组装、PCS功能、BMS与EMS分工,以及SOC、DOD等关键运维参数,帮助新人快速理解储能系统的核心技术和应用场景。

weixin_42522964的博客 594

Spring AOP面向切面源码解析

IoC 和 AOP 被称为 Spring 两大基础模块 AOP(Aspect-Oriented Programming) 在程序设计领域拥有其不可替代的适用场景和地位。Spring AOP 作为 AOP 思想的实现 public interface IService { void sayHello(); void sayHelloTo(String name); void sayByebye(); void sayByebyeTo(String name); } @Serv

ejinxian的专栏 282

【低空经济】无人机充电站设计方案

随着无人机技术的快速发展和广泛应用,其在物流、农业、巡检、救援等领域的应用日益普及。然而,无人机的续航能力一直是限制其大规模应用的关键因素之一。为了解决这一问题,无人机充电站的设计与建设显得尤为重要。本项目旨在设计一套高效、智能、可扩展的无人机充电站系统,以满足不同场景下无人机的充电需求,提升其作业效率和应用范围。无人机充电站的设计将围绕以下几个核心目标展开:首先,充电站应具备快速充电能力,以减少无人机的停机时间,提高作业效率;

2960

从源码解读Spring的AOP

概念 IOC和AOP作为Spring的两大核心,如果你接触过Spring框架,那就一定需要了解这两个核心部分的工作原理。IOC控制反转(或者说依赖注入)的部分已经在我的从源码解读Spring的IOC文章中有介绍,这篇文章主要来讲解AOP面向切面编程的原理 AOP,即Aspect Oriented Programming,面向切面编程,关于什么是面向切面编程,为了避免喧宾夺主,我在这里不进行过多的探...

Ekmr的博客 4504

163种中草药图像数据集构建与ResNet-50迁移学习实战指南

在计算机视觉领域,高质量标注数据集是模型训练的基石,直接影响图像分类、目标检测等任务的性能。其核心原理在于为算法提供结构化的监督信号,通过深度学习模型学习从像素到语义的映射关系。构建此类数据集的技术价值在于解决了特定垂直领域(如中医药)数据稀缺的痛点,为AI技术落地提供了关键“燃料”。在应用场景上,标准化数据集广泛支撑着教学演示、算法验证和产业应用开发。本文聚焦于中草药识别这一细分领域,详细介绍了一个包含163种常见药材、经过多源聚合与清洗的图像数据集构建全过程,并提供了基于PyTorch和ResNet-5

weixin_33672400的博客 455

Cesium高效渲染海量GeoJSON数据的7种优化策略与实战解析

本文深入解析Cesium高效渲染海量GeoJSON数据的7种优化策略,包括瓦片化转换、LOD分级加载、数据简化等关键技术。通过实战案例展示如何解决渲染卡顿问题,提升矢量数据加载性能,实现流畅的60FPS交互体验。特别针对GeoJSON大数据量场景提供完整优化方案。

h0i1j2k3l的博客 934

Spring Boot源码解读与原理分析

最近机缘巧合之下,读到了LinkedBear编写的《Spring Boot源码解读与原理分析》这本书,本人花了一周的时间认真研读了一下这本书,真的是受益匪浅,特此推荐给大家,好书不容错过啊。 文章目录 1. 关于作者 2. 本书定位 3. 目标读者 4. 读后感受 5. 书籍特点 6. 总结与展望 LinkedBear是一名资深的Java开发工程师,他倾力研究Spring技术体系多年,对Spring、Spring Boot、MyBatis等框架有独到的见解,拥有丰富的框架体系实践经验和架构封装经验。

herosunly的博客 5万+

AIDD-人工智能药物设计-构建基于机器学习方法的在线预测平台高准确预测药物诱导骨毒性

在此基础上,提取多种药物分子特征,包括分子指纹(如MACCS、Morgan、RDKit、TopologicalTorsion、AtomPairs与Descriptors)及分子图谱,通过Transformer编码器与神经网络进行机器学习模型训练。最后,将训练好的模型部署为在线Web服务器(BoneToxPD),供用户快速预测药物的骨毒性。本研究不仅在骨毒性预测的准确性方面取得了突破,还在模型解释性方面提供了新的视角,通过注意力机制精准识别出影响骨毒性的关键化学基团,推动药物研发领域更安全、更高效的发展。

itwangyang520的博客 1080

Spring源码解读(3)AOP-切面类的注解处理

1、概述     Aop是面向接口的,也即是面向方法的,实现是在IOC的基础上,Aop可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如Spring的事务,通过事务的注解配置,Spring会自动在业务方法中开启、提交业务,并且在业务处理失败时,执行相应的回滚策略,aop的实现主要包括了两个部分: 匹配符合条件的方法(Pointcut) 对匹配的方法...

weixin_34185560的博客 2229

13、无人机网络安全攻击检测:入侵检测系统综述

本文综述了无人机网络(FANETs)中的网络安全攻击与入侵检测系统(IDS)研究进展。文章介绍了无人机网络的架构设计、路由协议分类及移动模型,重点分析了DoS、DDoS、病毒蠕虫和零日攻击等常见安全威胁,并系统梳理了网络型、主机型、签名型、异常型、混合型等多种IDS的技术原理与应用。通过对比不同攻击类型及其检测机制,提出了综合使用多类IDS、更新签名库、优化路由、加强加密和建立应急响应等安全防护建议。同时展望了人工智能、量子安全和融合安全架构等未来发展趋势,旨在为提升无人机网络的安全性提供全面的技术参考。

wasm7browser的博客 162

常说的cache机制到底是什么?L1 cache和 L2 cache是什么?

一文带你迅速了解CPU内的cache机制!!图解多核CPU中的多级cache结构。为何有的处理器没有cache?

车载系统攻城狮 5878

《Spring Boot源码解读与原理剖析》

《Spring Boot源码解读与原理剖析》

啊Q老师 3594

修改 Alist 密码时报错?看看这个坑怎么解决!

启动服务后,再修改密码”。以后再遇到类似问题,先检查服务是否正常运行,说不定就能少踩不少坑。如果还有其他 Alist 的问题,欢迎在评论区留言交流~

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1154

Spring源码解读笔记

第一部分 Spring概述 1. Spring简介 Spring 是分层的轻量级开源框架,以IoC和AOP为内核,提供展现层SpringMVC和业务层事务管理等众多企业级应用技术,可以整合众多著名第三方框架和类库,成为使用最多的Java EE企业应用开源框架。 2. Spring优势 解耦合,简化开发:提供IoC容器,将对象间的依赖关系交由Spring控制,避免硬编码造成程序耦合,用户可以更专注于上层的应用。 AOP编程支持:提供AOP功能,方便进行面向切面编程。 声明式事务支持:可以通过声明式事务灵活进

郭靖宇的个人博客 1084

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Spring AOP(面向切面编程)

这里,getTransactionAttribute()获取事务属性,txMgr.getTransaction()开始事务,mi.proceed()执行目标方法,根据结果或异常决定提交或回滚事务。切点匹配是通过AspectJExpressionPointcut的matches()方法实现的,该方法使用AspectJ的编译时编织(CTW)和运行时编织(RTW)的API。proceed()方法调用JoinPoint的proceed(),如果抛出异常,afterThrowing()会被调用。

宽带你的世界 773

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Spring Boot源码解读与原理剖析:深入探索Java开发的奥秘!

本书前身是掘金社区销量TOP的小册——《Spring Boot源码解读与原理剖析》,整个社区中有3600+开发者都不约而同地选择了这本小册,也使它成为掘金社区首屈一指的王牌Spring教程,非常能打!经过多年的苦心钻研,他已经形成了对Spring、Spring Boot等框架独到的见解,拥有了丰富的框架体系实践经验和架构封装经验。在实践中,LinkedBear深切地感受到:虽然Spring Boot使用者的数量日益增加,但知道其背后原理的人着实不多,能深入源码、探寻源码最底层的人更是少之又少。

java李阳勇的博客 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

3.Spring 源码解读—IOC容器初始化过程

自1.1.3版本提供的抽象实现,提供bean工厂刷新方法的实现,可以配置是否允许重写bean定义以及循环依赖。AbstractRefreshableConfigApplicationContext子类则增加了资源配置入口,通过Environment解析出配置的真实资源路径字符串。它的子类实现是指定了资源的加载方式,比如XML资源方式的子类实现:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext。

RubyWinner的博客 1064

Spring AOP 源码解读

name: spring-aop-source title: Spring AOP 源码解析 date: 2020-03-25 15:03:38 tags: spring-aop-source categories: 文章目录前言本文使用的调试代码IOC 容器管理 AOP 实例ProxyFactory 详解基于注解的 Spring AOP 源码分析闲聊 InstantiationAwareBeanPostProcessor小结 之前写过 IOC 的源码分析,那篇文章真的有点长,看完需要点耐心。很多读者希.

孤刺 4074

【Spring Boot】Spring Boot源码解读与原理剖析

事实上,Spring Boot本身设计强大、巧妙,内部蕴含着令许多开发者和使用者争相学习的设计思想。通过研究SpringBoot与Spring Framework的源码与底层设计,相信可以使开发者的能力更上一层楼

小洁洁 3609

20.SpringBoot源码解读

/针对类,Annotation注解方式>) {>) source);return;//针对Resource,xml配置return;//针对包,sanner扫描return;//针对字符串,转换为类,resource,包return;

RubyWinner的博客 2478

47.Spring源码面试怎么面?

文章目录前言1.Spring框架的优点和缺点:1.1优点1.2缺点:2.Spring核心组件讲解:3.Spring流程总结和常用注解:4.SpringMvc和SpringBoot:5.Spring和mybatis的集成源码解读:总结 前言 Spring框架是我们现在java后端使用最多的框架,SpringMvc->SpringBoot,而其中的源码面试也是我们经常面试中会被问的,如果没看过源码,没了解过源码总结,只会使用,那么面试基本就会挂掉。本篇文章谈谈我对Spring源码的总结,来帮助大家能够更好

u010720120的博客 1412

Spring解读系列目录

最近因为工作需要笔者从官网从源码中学习了大量的Spring框架的内容,学习过程中发现有些同事对于怎么学习框架非常的迷惑和吃力,花了大量的时间也没有什么好的效果。我相信网上的各位同学一定也有这样的困惑。其实笔者认为学习框架固然枯燥,但是如果有钻研的劲头其实也可以做到很有成就感。看过笔者之前的贴子的同学应该有一个感觉,笔者进行这些理论研读的时候总是喜欢做一些小例子进行辅助理解。其实这也是笔者学习框架的一个特点吧,如果看到一个知识点,笔者会比较倾向把这个知识点模拟出来,然后通过对比大神的源码进一步分析理解,以达到

Smallc0de的博客 2634

Spring Ai Alibaba Graph源码解读系列—action

从今天起,我们来系统梳理下Spring Ai Alibaba Graph的源码,会给出各个部分的功能、作用,以及会新增许多Graph的案例,初步会在一个月内完结。因为目前相关代码正在快速迭代中,维护的飞书在线云文档会同步最新的源码解读及案例,让我们持续跟进业界最新技术,Let’s Go!本期先介绍action部分,主要是接收OverAllState、RunnableConfig对节点、边触发相应的动作。

yingzi的技术博客 559

spring源码解读

1、IOC(控制反转)、AOP(切面)、DI (依赖注入)是spring的核心部分 Spring是一种设计思想的体现,发生了“主从换位”的变化。应用程序由主动的创建对象,转换称了从IOC容器里获取对象,对象的创建、解析和注册都由Spring来替用户实现,用户只管定义。 2、IoC容器的设计与实现--Bean组件与Context组件 使用Spring时,它首先替我们完成的时IOC容器的...

snow的博客 1万+

从基础到应用到源码解读,阿里爆款Spring深度源码分析笔记太香了

事实上,无论是国内还是国外,Spring 的热度走势一直都是特别健康的,我们可以这么说,Spring 已然成为了 Java 开发的标杆、灯塔级别的“标准”,熟练掌握SpringFramework,甚至精通它,对于进军大厂,获取高薪来说是相当的有必要。Spring 作为一个轻量级的 Java 开发框架,将面向接口的编程思想贯穿整个 Java 系统应用,因此在 Java 面试中常被提。对于Java开发小伙伴来说,Spring 框架熟悉又陌生。面试的时候总会被问到深入底层源码的东西!

jjc4261的博客 848

Dubbo源码解读-dubbo启动与Spring整合之@ DubboComponentScan

本文主要@ DubboComponentScan注解功能进行源码说明。上篇我们介绍了Dubbbo整合Spring中的@EnableDubboConfig注解源码分析,地址如下。接着说明,读Dubbo源码最好是先对Spring源码有一定的了解。如果大家需要,我也可以针对Spring框架做一系列源码的解读专栏。不过不用担心,如果需要Spring的源码知识,文章中也会进行Spring源码铺垫介绍的。

胖墩儿没腹肌 1614
上一篇: maven排包排不掉问题
下一篇: rocketMq源码启动
掀衣怒码
博客等级 码龄6年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值