尚硅谷spring框架视频教程——学习笔记一(IOC、AOP)
文章目录
- 前言
- 一、控制反转(IOC)
- 1. 底层原理
- 2. 两种实现方式(接口)
- 3. bean管理(基于xml方式)
- 4. bean管理(基于注解方式)
- 二、面向切面编程(AOP)
- 1. 底层逻辑
- 2. 基于注解开发
前言
虽然不懂消化原理也不妨碍消化食物,但还是对消化原理感兴趣。
一、控制反转(IOC)
控制反转,就是把创建对象和对象之间的调用过程交给spring进行管理,以降低代码之间的耦合度。
1. 底层原理
控制反转是基于:xml解析、工厂模式和反射三部分实现的。
(1)创建对象及对象间调用的相关信息配置在配置文件中,spring通过xml解析获取相关信息;
(2)通过工厂模式将调用的类与被调用的类解耦;
(3)在工厂类中,使用获取到的配置信息,通过反射创建对象并设置属性;
2. 两种实现方式(接口)
(1)BeanFactory:加载配置文件时不创建对象,获取对象(使用)时才创建;
(2)ApplicationContext:BeanFactory的子接口,加载配置文件的时候就会创建对象,把耗费时间的步骤放在服务器启动的时候;
3. bean管理(基于xml方式)
(1)创建对象
- 使用bean标签注入创建对象,默认调用无参的构造函数
(2)注入属性
- set方法注入属性
- 有参构造函数注入属性
- p名称空间注入(了解)
- 使用null标签注入空值
- 特殊字符的注入可写到<![CDATA[]]>中
- 通过ref注入外部bean
- 使用array标签、list标签、map标签(内部使用entry标签)、set标签注入集合
- 使用util名称空间(如
<util:list>)提取重复注入部分
(3)工厂bean
- 区别
普通bean:在bean标签中定义什么类型,就返回什么类型;
工厂bean:定义的类型和返回的类型可以不一致; - 实现
创建类,实现FactoryBean接口,并定义泛型;
实现getObject方法;
(4)bean的作用域(单实例或多实例)
通过bean标签中的scope属性设置作用域,默认是单实例(singleton,加载配置文件时创建对象),还可以设置为多实例(property,调用getBean时才创建对象)、请求(request,了解即可)、会话(session,了解即可)
(5)bean生命周期
配置后置处理器可在创建对象过程中加入一些自定义逻辑,如属性修改、依赖注入增强等。注意:配置后置处理器之后,默认会为当前配置文件中的所有bean都配置上后置处理器
- 通过无参构造创建bean实例;
- 设置属性值以及对其他bean的引用
- 把bean实例传给后置处理器的postProcessBeforeInitialization方法(实现BeanPostProcessor接口)
- 调用bean的初始化方法(通过bean标签中的init-method属性设置)
- 把bean实例传给后置处理器的postProcessAfterInitialization方法(实现BeanPostProcessor接口)
- 获取到bean对象,并使用
- 当容器关闭时(手动调用context的close方法),调用bean的销毁方法(通过bean标签中的destroy-method属性设置)
(6)自动装配
在bean标签中,通过autowire配置自动装配方式,根据属性名称(byName)或者属性类型(byType)
(7)引入外部属性文件
比如数据库的配置可以放到properies为后缀的文件中,通过context名称空间引入外部属性文件,然后在设置属性值时,通过${}获取相应配置
4. bean管理(基于注解方式)
(1)什么是注解
注解是代码中的特殊标记,基本模式为@注解名称(属性名称=属性值),可以作用在类、方法、属性上。使用注解的目的是简化xml配置。
(2)开启组件扫描
可配置只扫描或者不扫描某种注解。
- 可以使用命名空间context,并设置base-package的属性值
- 也可以使用完全注解开发
@Configuration
@ComponentScan(basePackages = {"com.xxx"})
public class SpringConfig {
}
(3)创建对象的注解
功能都是一样的,只是习惯加以区分。value的属性值可以不写,默认是将类名称的首字母改成小写
- @Component(value=“xxx”):用于普通的类对象
- @Controller(value=“xxx”):一般用在web层
- @Service(value=“xxx”):一般用在业务逻辑层
- @Repository(value=“xxx”):一般用在数据访问层(DAO层)
(4)注入属性的注解
- @Autowired:根据属性类型注入类对象,属于spring的包
- @Qualifier(value=xxx):根据属性名称注入类对象,属于spring的包
需要和@Autowired一起使用 - @Resource(name=xxx):根据类型/名称注入类对象,属于javax的包
- @Value(value=xxx):注入普通类型属性
二、面向切面编程(AOP)
不修改原有代码的前提下,在主干逻辑中添加新功能,降低业务逻辑各部分之间的耦合度,比如为登录功能加上权限控制。
1. 底层逻辑
(1)有接口,使用JDK动态代理
代理对象和目标对象都实现同一个接口,代理对象方法内部调用目标对象的相应方法。代码来自
// 目标接口
public interface OrderService {void add();
}
// 目标类
public class OrderServiceImpl implements OrderService {@Overridepublic void add() {System.out.println("添加用户");}
}
// 代理类
public class OrderServiceProxy implements OrderService {@Overridepublic void add() {long begin = System.currentTimeMillis();OrderService.add();long end = System.currentTimeMillis();System.out.println("耗时"+(end - begin)+"毫秒");}
}
代码实现使用了java.lang.reflect.Proxy的newProxyInstance方法。第一个参数:类加载器;第二个参数:接口类型;第三个参数:调用得到处理器代码来自
public class ProxyHandler implements InvocationHandler {private Object targetObject;//被代理的对象public Object newProxyInstance(Object targetObject){this.targetObject = targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);}//该方法在代理对象调用方法时调用@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("记录日志");return method.invoke(targetObject,args);}
}
(2)没有接口,使用CGLIB动态代理
代理对象继承目标类,重写相应的方法,并使用super.xxx()调用父类方法
// 目标类
public class OrderService {public void add() {System.out.println("添加用户");}
}
// 代理类
public class OrderServiceProxy extends OrderService {@Overridepublic void add() {long begin = System.currentTimeMillis();super.add();long end = System.currentTimeMillis();System.out.println("耗时"+(end - begin)+"毫秒");}
}
2. 基于注解开发
(1)操作术语
- 连接点:类中可以被增强的方法
- 切入点:实际被增强的方法
- 通知(增强):实际增强的逻辑部分
- 切面:是动作,把通知应用到切入点的过程
(2)使用方法
- 开启组件扫描(@ComponentScan),开启生成代理对象(@EnableAspectJAutoProxy(proxyTargetClass = true))
- 创建类,在类中写主干逻辑
- 创建增强类,编写增强逻辑,在类上加@Aspect注解(用于标识一个类为切面)
(3)五种通知类型
前置(@Before)、后置(@AfterReturning有异常不执行)、环绕(@Around环绕之后有异常不执行)、异常(@AfterThrowing)、最终(@After)
切入点表达式为execution([权限修饰符][返回类型][类全路径][方法名称](参数列表)),权限修饰符:public/private/protected,一般直接写*,表示不限制;返回类型可以不写。
// 配置类
@Configuration
@ComponentScan(basePackages={"com.atguigu"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop() {}// 主干逻辑
@Component
public class User {public void add() {System.out.println("add主逻辑");}
}// 增强类
// 多个增强类对同一个方法进行增强,设置优先级,数字越小优先级越高
@Order(1)
@Aspect
@Component
public class UserProxy{// 相同切入点的抽取@Pointcut(value="execution(* com.atguigu.dao.BookDao.add(..))")public void pointdemo() {}// 对com.atguigu.dao.BookDao类里的add方法进行增强@Before(value="execution(* com.atguigu.dao.BookDao.add(..))")public void before() {System.out.println("增强的逻辑");}@After(value="pointdemo()")public void after() {System.out.println("增强的逻辑");}
}
相关文章:
尚硅谷spring框架视频教程——学习笔记一(IOC、AOP)
文章目录 前言一、控制反转(IOC)1. 底层原理2. 两种实现方式(接口)3. bean管理(基于xml方式)4. bean管理(基于注解方式) 二、面向切面编程(AOP)1. 底层逻辑2.…...
傅里叶分析之掐死教程
https://zhuanlan.zhihu.com/p/19763358 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析 不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是,傅里叶分析的公式看起来太复杂了,所以很多…...
实战:如何快速让新网站被百度收录?
本文来自:百万收录网 原文链接:https://www.baiwanshoulu.com/22.html 要让新网站快速被百度收录,可以采取以下实战策略: 一、网站基础优化 网站结构清晰:确保网站的结构简洁清晰,符合百度的抓取规则。主…...
PVE 虚拟机安装 Debian 无图形化界面服务器
Debian 安装 Debian 镜像下载 找一个Debian镜像服务器,根据需要的版本和自己硬件选择。 iso-cd/:较小,仅包含安装所需的基础组件,可能需要网络访问来完成安装。有镜像 debian-12.9.0-amd64-netinst.isoiso-dvd/:较…...
Java定时任务实现方案(五)——时间轮
时间轮 这篇笔记,我们要来介绍实现Java定时任务的第五个方案,使用时间轮,以及该方案的优点和缺点。 时间轮是一种高效的定时任务调度算法,特别适用于大量定时任务的场景。时间轮的定时任务实现,可以使用DelayQueue…...
乐理笔记——DAY02
三分钟音乐社视频地址: 调号总结篇https://www.bilibili.com/video/BV14p4y1e7TV?spm_id_from333.788.videopod.episodes&vd_source0a2d366696f87e241adc64419bf12cab&p25https://www.bilibili.com/video/BV14p4y1e7TV?spm_id_from333.788.videopod.epis…...
企业知识管理在推动组织变革与适应性发展中的关键性作用分析
内容概要 企业知识管理是信息时代背景下的重要管理理念,旨在通过有效地获取、分享和再利用知识,提升组织在变革中的灵活性和创新能力。知识作为企业的重要资产,其有效管理不仅影响到日常运营,更是推动组织变革与适应性发展的核心…...
动态规划DP 最长上升子序列模型 登山(题目分析+C++完整代码)
概览检索 动态规划DP 最长上升子序列模型 登山 原题链接 AcWing 1014. 登山 题目描述 五一到了,ACM队组织大家去登山观光,队员们发现山上一共有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个…...
芯片AI深度实战:进阶篇之vim内verilog实时基于AST的自定义检视
本文基于Editor Integration | ast-grep,以及coc.nvim,并基于以下verilog parser(my-language.so,文末下载链接), 可以在vim中实时显示自定义的verilog 匹配。效果图如下: 需要的配置如下: 系列文章: 芯片…...
AI 计算的未来:去中心化浪潮与全球竞争格局重塑
引言 人工智能(AI)正以前所未有的速度发展,尤其是大模型训练和推理效率的提升,使得 AI 计算成本迅速下降,呈现出向去中心化演进的趋势。 最新的 DeepSeek r1 模型,以仅 600 万美元 的训练成本,达到了 OpenAI o1 级别的性能,表明 AI 技术正迈向更具普惠性的阶段。这一趋…...
JxBrowser 8.2.2 版本发布啦!
JxBrowser 8.2.2 版本发布啦! • 已更新 #Chromium 至更新版本 • 实施了多项质量改进 🔗 点击此处了解更多详情。 🆓 获取 30 天免费试用。...
BWM 世界模型
DGX AGX Ominiverse With Cosmos 功能 1w 张 H100 训练了 3个月 使用 Ray 串流 数据 数据准备 处理 pipeline 数组组成 真实世界的物理数据 训练 1、使用 L1 损失,最小化 输入和重构视频之间的像素级差异 以及基于 VGG19 的一个特征感知损失 2、使用光流的损…...
@Inject @Qualifier @Named
Inject Qualifier Named 在依赖注入(DI)中,Inject、Qualifier 和 Named 是用于管理对象创建和绑定的关键注解。以下是它们的用途、依赖配置和代码示例的详细说明: 1. 注解的作用 Inject:标记需要注入的构造函数、字段…...
【已解决】windows7虚拟机安装VMtools频繁报错
为了在虚拟机VMware中安装win7,题主先在网上下载了windows7 professional版本的镜像,在vmware中安装vmtools时报错,信息如下 (安装程序无法继续,本程序需要您将此虚拟机上安装的操作系统更新到SP1) 然后就…...
【PyTorch】6.张量运算函数:一键开启!PyTorch 张量函数的宝藏工厂
目录 1. 常见运算函数 个人主页:Icomi 专栏地址:PyTorch入门 在深度学习蓬勃发展的当下,PyTorch 是不可或缺的工具。它作为强大的深度学习框架,为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术&…...
【自学笔记】MySQL的重点知识点-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 MySQL重点知识点MySQL知识点总结一、数据库基础二、MySQL的基本使用三、数据类型四、触发器(Trigger)五、存储引擎六、索引七、事务处理八、…...
SSM开发(八) MyBatis解决方法重载
目录 一、Mybatis能否支持方法重载? 二、解决 MyBatis 方法重载问题的几种方法 解决方法一: (注解方式) 将重载方法命名为不同的方法名 解决方法二:采用@SelectProvider注解 解决方法三:使用 MyBatis 的 标签和动态 SQL 来构建不同参数的 SQL 查询 三、总结 一、Myb…...
PyTorch 快速入门
我们将通过一个简单的示例,快速了解如何使用 PyTorch 进行机器学习任务。PyTorch 是一个开源的机器学习库,它提供了丰富的工具和库,帮助我们轻松地构建、训练和测试神经网络模型。以下是本教程的主要内容: 一、数据处理 PyTorch…...
【浏览器 - Mac实时调试iOS手机浏览器页面】
最近开发个项目,需要在 Mac 电脑上调试 iOS 手机设备上的 Chrome 浏览器,并查看Chrome网页上的 console 信息,本来以为要安装一些插件,没想到直接使用Mac上的Safari 直接可以调试,再此记录下,分享给需要的伙…...
PyQt5之QtDesigner的若干配置和使用
1.描述 QtDesigner是一个可视化工具,可以通过该工具设计页面 2.简单使用 1.下载PyQt5-tools pip install pyqt5-tools 2.打开designer.exe文件 我采用的是虚拟环境,该文件位于C:\Users\24715\anaconda3\envs\pyqt\Lib\site-packages\qt5_applicatio…...
Flink (十二) :Table API SQL (一) 概览
Apache Flink 有两种关系型 API 来做流批统一处理:Table API 和 SQL。Table API 是用于 Scala 和 Java 语言的查询API,它可以用一种非常直观的方式来组合使用选取、过滤、join 等关系型算子。Flink SQL 是基于 Apache Calcite 来实现的标准 SQL。无论输入…...
侯捷C++day01
一个类该准备什么样的数据、函数。才能满足使用这个类人的需求。 inline关键字是建议编译器做inline处理。 private只有本类可以看到。 C创建对象会自动调用构造函数。不可能在程序中显示调用构造函数。不带指针的类多半不用写析构函数。 以下两个重载构造函数会发生错误 不允许…...
CTF-web: phar反序列化+数据库伪造 [DASCTF2024最后一战 strange_php]
step 1 如何触发反序列化? 漏洞入口在 welcome.php case delete: // 获取删除留言的路径,优先使用 POST 请求中的路径,否则使用会话中的路径 $message $_POST[message_path] ? $_POST[message_path] : $_SESSION[message_path]; $msg $userMes…...
Win11下帝国时代2无法启动解决方法
鼠标右键点图标,选择属性 点开始,输入启用和关闭...
GSI快速收录服务:让你的网站内容“上架”谷歌
辛苦制作的内容无法被谷歌抓取和展示,导致访客无法找到你的网站,这是会让人丧失信心的事情。GSI快速收录服务就是为了解决这种问题而存在的。无论是新上线的页面,还是长期未被收录的内容,通过我们的技术支持,都能迅速被…...
如何用函数去计算x年x月x日是(C#)
如何用函数去计算x年x月x日是? 由于现在人工智能的普及,我们往往会用计算机去算,或者去记录事情 1.计算某一年某一个月有多少天 2.计算某年某月某日是周几 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadin…...
mysql_init和mysql_real_connect的形象化认识
解析总结 1. mysql_init 的作用 mysql_init 用于初始化一个 MYSQL 结构体,为后续数据库连接和操作做准备。该结构体存储连接配置及状态信息,是 MySQL C API 的核心句柄。 示例: MYSQL *conn mysql_init(NULL); // 初始化连接句柄2. mysql_…...
python学opencv|读取图像(四十九)原理探究:使用cv2.bitwise()系列函数实现图像按位运算
【0】基础定义 按位与运算:两个等长度二进制数上下对齐,全1取1,其余取0。 按位或运算:两个等长度二进制数上下对齐,有1取1,其余取0。 按位异或运算: 两个等长度二进制数上下对齐,相…...
基础项目实战——学生管理系统(c++)
目录 前言一、功能菜单界面二、类与结构体的实现三、录入学生信息四、删除学生信息五、更改学生信息六、查找学生信息七、统计学生人数八、保存学生信息九、读取学生信息十、打印所有学生信息十一、退出系统十二、文件拆分结语 前言 这一期我们来一起学习我们在大学做过的课程…...
春节期间,景区和酒店如何合理用工?
春节期间,景区和酒店如何合理用工? 春节期间,旅游市场将迎来高峰期。景区与酒店,作为旅游产业链中的两大核心环节,承载着无数游客的欢乐与期待。然而,也隐藏着用工管理的巨大挑战。如何合理安排人力资源&a…...
