当前位置: 首页 > news >正文

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】

😀前言
手动实现 Spring 底层机制的第2篇 实现了任务阶段一编写自己 Spring 容器-准备篇【2】

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 😀手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】
    • 创建SmartAnimalable接口
    • 创建SmartDog类
    • 创建SmartAnimalAspect切面类
    • 修改类beans.xml
    • 创建AppMain类
    • 输出结果
  • 😄简单分析
    • AOP 和 BeanPostProces关系
    • 看一下 AnnotationAwareAspectJAutoProxyCreator 的类图
    • 分析
    • 😄总结

😀手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】

创建SmartAnimalable接口

public interface SmartAnimalable {float getSum(float i, float j);float getSub(float i, float j);
}

创建SmartDog类

@Component
public class SmartDog implements SmartAnimalable {public float getSum(float i, float j) {float res = i + j;System.out.println("SmartDog-getSum-res=" + res);return res;}public float getSub(float i, float j) {float res = i - j;System.out.println("SmartDog-getSub-res=" + res);return res;}
}

创建SmartAnimalAspect切面类

@Component
@Aspect
public class SmartAnimalAspect {//给SmartDog配置前置,返回,异常,最终通知//前置通知@Before(value = "execution(public float com.wyxde.spring.aop.SmartDog.getSum(float, float))")public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showBeginLog()[使用的myPointCut()]-方法执行前-日志-方法名-" + signature.getName() + "-参数 "+ Arrays.asList(joinPoint.getArgs()));}//返回通知@AfterReturning(value = "execution(public float com.wyxde.spring.aop.SmartDog.getSum(float, float))", returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res);}//异常通知@AfterThrowing(value = "execution(public float com.wyxde.spring.aop.SmartDog.getSum(float, float))", throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable);}//最终通知@After(value = "execution(public float com.wyxde.spring.aop.SmartDog.getSum(float, float))")public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showFinallyEndLog()-方法最终执行完毕-日志-方法名-" + signature.getName());}}

修改类beans.xml

配置自动扫描的包, 同时引入对应的名称空间

  1. 如果我们是普通的java项目, beans.xml 放在src下
  2. 如果我们是java maven 项目, beans.xml 放在 src/main/resources
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.wyxde.spring.component"/><context:component-scan base-package="com.wyxde.spring.aop"/><!--启用基于注解方式的AOP功能--><aop:aspectj-autoproxy/><!--配置后置处理器--><bean class="com.wyxde.spring.process.MyBeanPostProcessor" id="myBeanPostProcessor"/>
</beans>

创建AppMain类

public class AppMain {public static void main(String[] args) {//测试看看是否可以得到spring容器中的bean , 同时看看依赖注入是否OKApplicationContext ioc =new ClassPathXmlApplicationContext("beans.xml");UserAction userAction = (UserAction) ioc.getBean("userAction");UserAction userAction2 = (UserAction) ioc.getBean("userAction");System.out.println("userAction=" + userAction);System.out.println("userAction2=" + userAction2);UserDao userDao = (UserDao) ioc.getBean("userDao");System.out.println("userDao=" + userDao);UserService userService = (UserService) ioc.getBean("userService");System.out.println("userService=" + userService);//测试一下当前的依赖注入userService.m1();//测试一下AOPSmartAnimalable smartDog = ioc.getBean(SmartAnimalable.class);smartDog.getSum(10, 2);}
}

输出结果

img

😄简单分析

AOP 和 BeanPostProces关系

  1. AOP 实现 Spring 可以通过给一个类,加入注解 @EnableAspectJAutoProxy 来指定, 比

img

  1. 我们来追一下@EnableAspectJAutoProxy

img

img

img

img

img

img

看一下 AnnotationAwareAspectJAutoProxyCreator 的类图

img

分析

  1. AOP 底层是基于 BeanPostProcessor 机制的.

  2. 即在 Bean 创建好后,根据是否需要 AOP 处理,决定返回代理对象,还是原生 Bean

  3. 在返回代理对象时,就可以根据要代理的类和方法来返回

  4. 其实这个机制并不难,本质就是在 BeanPostProcessor 机制 + 动态代理技术

  5. 下面我们就准备自己来实现 AOP 机制, 这样小伙伴们就不在觉得 AOP 神秘,通透很多了.

😄总结

到本文为止以及全部完成了准备了下一篇就开始正式手动实现 Spring 底层机制

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】系列

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【1】

😁热门专栏推荐
想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集
linux合集
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

相关文章:

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】

&#x1f600;前言 手动实现 Spring 底层机制的第2篇 实现了任务阶段一编写自己 Spring 容器-准备篇【2】 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的…...

部署模型并与 TVM 集成

本篇文章译自英文文档 Deploy Models and Integrate TVM tvm 0.14.dev0 documentation 更多 TVM 中文文档可访问 →Apache TVM 是一个端到端的深度学习编译框架&#xff0c;适用于 CPU、GPU 和各种机器学习加速芯片。 | Apache TVM 中文站 本节介绍如何将 TVM 部署到各种平台&…...

Android Navigation 导航切换fragment用法

对于Android Navigation组件的导航到Fragment&#xff0c;您可以按照以下步骤操作&#xff1a; 首先&#xff0c;在您的项目的build.gradle文件中添加Navigation依赖&#xff1a; dependencies {def nav_version "2.3.4"implementation "androidx.navigation…...

Anaconda Prompt使用pip安装PyQt5-tools后无法打开Spyder或闪退

艹&#xff01;MLGBZD! 真TMD折腾人&#xff01; 出现原因&#xff1a; 首次安装完Anaconda3-2023.07-1-Windows-x86_64.exe后首次打开Spyder&#xff0c;此时是没有问题的&#xff0c;然后打开Anaconda Prompt&#xff0c;查看有哪些包&#xff0c;pip list 这时候开始首次安…...

【jvm】jvm整体结构(hotspot)

目录 一、说明二、java代码的执行流程三、jvm的架构模型3.1 基于栈式架构的特点3.2 基于寄存器架构的特点 一、说明 1.hotspot vm是目前市场上高性能虚拟机的代表作之一 2.hotspot采用解释器与即时编译器并存的架构 3.java虚拟机是用来解释运行字节码文件的&#xff0c;入口是字…...

通达信波段选股公式,使用钱德动量摆动指标(CMO)

钱德动量摆动指标(CMO)是由图莎尔钱德发明的&#xff0c;取值范围在-100到100之间&#xff0c;是捕捉价格动量的技术指标。该指标计算近期涨幅之和与近期跌幅之和的差值&#xff0c;然后将计算结果除以同期所有价格波动的总和。本文的波段选股公式使用均线识别趋势&#xff0c;…...

家电维修小程序开发指南:从零搭建到上线

随着科技的发展和人们生活水平的提高&#xff0c;家电已经成为人们生活中不可或缺的一部分。然而&#xff0c;随之而来的是家电维修门店业务的繁忙和效率的考验。为了提高家电维修门店的效率和服务质量&#xff0c;建立一个便捷高效的小程序已成为必要的选择。 本文将介绍一个简…...

玩赚音视频开发高阶技术——FFmpeg

随着移动互联网的普及&#xff0c;人们对音视频内容的需求也不断增加。无论是社交媒体平台、电商平台还是在线教育&#xff0c;都离不开音视频的应用。这就为音视频开发人员提供了广阔的就业机会。根据这些年来网站上的音视频开发招聘需求来看&#xff0c;音视频开发人员的需求…...

python 变量赋值 修改之后 原值改变

python 是一种动态语言&#xff0c;因此变量的类型和值 在运行时均可改变。当我们将一个变量赋值给另一个变量时&#xff0c;实际上是将变量的引用地址传递给新的变量&#xff0c;这意 味着新旧变量将指向同一个位置。因此&#xff0c;在更改其中一个变量的值时&#xff0c;另一…...

拂袖一挥,zipfile秒列zip包内容

使用wxpython列出文件夹中的zip文件及内容 最近在做一个文件管理的小工具,需要列出选择的文件夹下的所有zip压缩文件,并在点击某个zip文件时能够显示其中的内容。为此我使用了wxpython来实现这个功能。 1. 导入需要的模块 首先导入程序需要的模块: import wx import os imp…...

InnoDB文件物理结构解析2 - FIL_PAGE_INDEX

1. 关于索引组织表 InnoDB使用的是索引组织表(IOT)的方式存储表记录&#xff0c;索引组织表以主键构建一个B-tree的数据结构来存储行记录&#xff0c;行记录存储在树的叶节点内。这与Oracle数据库是不同的&#xff0c;Oracle数据库默认创建的表是堆组织表(HOT)&#xff0c;HOT…...

XML-BEANS compiled schema: Could not locate compiled schema resource 异常处理

使用poi5.2.2生成ppt&#xff0c;生成堆叠图&#xff0c;设置值时抛出异常 XML-BEANS compiled schema: Could not locate compiled schema resource org/apache/poi/schemas/ooxml/system/ooxml/stoverlappercent872etype.xsb (org.apache.poi.schemas.ooxml.system.ooxml.st…...

IOC容器 - Autofac

DI&#xff08;依赖注入&#xff09;&#xff1a;DI&#xff08;Dependency Injection&#xff09;是一种实现松耦合和可测试性的软件设计模式。它的核心思想是将依赖关系的创建与管理交给外部容器&#xff0c;使得对象之间只依赖于接口而不直接依赖于具体实现类。通过依赖注入…...

用i18n 实现vue2+element UI的国际化多语言切换详细步骤及代码

一、i18n的安装 这个地方要注意自己的vue版本和i1n8的匹配程度&#xff0c;如果是vue2点几&#xff0c;记得安装i18n的8版本&#xff0c;不然会自动安装的最新版本&#xff0c;后面会报错哦&#xff0c;查询了下资料&#xff0c;好像最新版本是适配的vue3。 npm install vue-…...

Vue3 :Pinia入门

Vue3 &#xff1a;Pinia入门 Date: May 11, 2023 Sum: Pinia概念、实现counter、getters、异步action、storeToRefs保持响应式解构 什么是Pinia Pinia 是 Vue 的专属状态管理库&#xff0c;可以实现跨组件或页面共享状态&#xff0c;是 vuex 状态管理工具的替代品&#xff0c…...

Java线程池的类型和使用

Java线程池的类型和使用 引言 在并发编程中&#xff0c;线程池是一种非常重要的工具&#xff0c;它可以实现线程的复用&#xff0c;避免频繁地创建新线程&#xff0c;从而提高程序的性能和效率。Java的并发库提供了丰富的线程池功能&#xff0c;本文将介绍Java线程池的类型和…...

QT的信号槽的四种写法和五种链接方式

目录 四种信号槽写法&#xff1a; 五种连接方式&#xff1a; 实例&#xff1a; 常见错误及改正&#xff1a; 错误1: 未连接信号与槽 错误2: 信号和槽参数不匹配 错误3: 未使用Q_OBJECT宏 错误4: 跨线程连接未处理 在Qt中&#xff0c;信号&#xff08;Signal&#xff09…...

Vue+SpringBoot项目开发:后台登陆功能的实现(二)

写在开始:一个搬砖程序员的随缘记录文章目录 一、SpringBoot项目的搭建二、数据库配置1、新建数据库2、新建用户表 三、SpringBoot项目的配置 一、SpringBoot项目的搭建 项目搭建传送门&#xff1a;从零开始&#xff0c;SpringBoot项目快速搭建 二、数据库配置 1、新建数据库…...

arcgis pro 3.0.2 安装及 geemap

arcgis pro 3.0.2 安装及 geemap arcgis pro 3.0.2 安装 arcgis pro 3 版本已经很多了&#xff0c;在网上找到资源就可以进行安装 需要注意的是&#xff1a;有的文件破解文件缺少&#xff0c;导致破解不成功。 能够新建地图就是成功了&#xff01; geemap安装 1.需要进行环…...

oracle插入多表(insert all/first)

1、建测试表 CREATE TABLE EDW_INT (AGMT_NO VARCHAR2(40 BYTE) NOT NULL,AGMT_SUB_NO VARCHAR2(4 BYTE) NOT NULL,NEED_REPAY_INT NUMBER(22,2),CURR_PERIOD NUMBER(4) NOT NULL ); CREATE TABLE EDW_INT_1 (…...

手把手教你为UniApp微信小程序项目配置安全的WSS WebSocket连接(Vue3版)

从零构建UniApp微信小程序的WSS WebSocket全链路配置指南 微信小程序作为日活超4亿的超级入口&#xff0c;其安全策略要求所有网络请求必须通过HTTPS加密传输&#xff0c;这对WebSocket连接提出了WSS的强制要求。许多全栈开发者在项目上线时&#xff0c;往往卡在如何从普通WS服…...

R语言机器学习项目标准化模板与实战技巧

1. R语言机器学习项目模板解析作为一名在数据科学领域摸爬滚打多年的从业者&#xff0c;我深知机器学习项目的成功往往取决于系统化的执行流程。今天要分享的这个R语言机器学习项目模板&#xff0c;是我在完成近百个实际项目后提炼出的标准化框架。这个6步模板特别适合刚接触R语…...

Voxtral-4B-TTS-2603语音合成入门:标点符号(!?。)对语调与停顿的实际影响

Voxtral-4B-TTS-2603语音合成入门&#xff1a;标点符号&#xff08;&#xff01;&#xff1f;。&#xff09;对语调与停顿的实际影响 1. 引言 你是否遇到过这样的情况&#xff1a;使用语音合成工具生成的音频听起来机械生硬&#xff0c;缺乏自然的情感表达&#xff1f;其实&a…...

用户上周说有两个孩子,这周说有三个孩子,Agent 如何处理记忆冲突?

首先我们要直到mem0框架,这个框架和RAG类似,RAG存储的数据一般是偏静态偏共享的数据,这类数据一般可以被多人共享,但是mem0的数据一般是用户画像,是偏动态偏隐私的,但是二者的存储策略一般都是使用向量数据库 现在存的数据是用户的相关的数据,所以要使用到mam0框架,mem0的四个…...

NVIDIA Nemotron 3架构解析:智能体AI与混合Mamba-Transformer MoE设计

1. NVIDIA Nemotron 3架构解析&#xff1a;面向智能体AI的新一代模型设计在当今AI领域&#xff0c;智能体系统&#xff08;Agentic AI&#xff09;正变得越来越复杂。这类系统通常由多个协作的智能体组成——包括检索器、规划器、工具执行器和验证器等——它们需要在大量上下文…...

Kala ISO 8601调度语法详解:从基础时间格式到复杂间隔配置

Kala ISO 8601调度语法详解&#xff1a;从基础时间格式到复杂间隔配置 【免费下载链接】kala Modern Job Scheduler 项目地址: https://gitcode.com/gh_mirrors/ka/kala Kala作为一款现代作业调度器&#xff08;Modern Job Scheduler&#xff09;&#xff0c;采用ISO 86…...

GDB 调试完全指南:从入门到工程实战

GDB 调试完全指南&#xff1a;从入门到工程实战 这份教程旨在帮助你建立系统的调试思维&#xff0c;不仅掌握命令&#xff0c;更掌握解决复杂问题的方法。第一章&#xff1a;工欲善其事&#xff08;环境与配置&#xff09; 在开始调试之前&#xff0c;必须确保你的“武器”已经…...

langsmith-fetch技能:调试LangChain和LangGraph代理的必备工具

langsmith-fetch技能&#xff1a;调试LangChain和LangGraph代理的必备工具 【免费下载链接】awesome-codex-skills A curated list of practical Codex skills for automating workflows across the Codex CLI and API. 项目地址: https://gitcode.com/GitHub_Trending/aw/aw…...

机器学习中的统计显著性检验:方法与实战指南

1. 统计显著性检验在机器学习结果解读中的核心价值当我们在Kaggle上拿到一个不错的分数&#xff0c;或者在业务场景中看到模型指标提升了2%&#xff0c;最常被问到的问题是&#xff1a;这个结果真的可靠吗&#xff1f;还是只是随机波动&#xff1f;三年前我在电商推荐系统优化时…...

量子机器学习:原理、算法与工程实践

1. 量子机器学习&#xff1a;当传统算力遇到物理极限 三年前我在处理一个蛋白质折叠预测项目时&#xff0c;第一次真切感受到经典计算机的算力瓶颈。当模型参数超过1亿&#xff0c;即使使用最先进的GPU集群&#xff0c;训练周期仍然长达两周。正是那次经历让我开始关注量子计算…...