尚硅谷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)操作术语

  1. 连接点:类中可以被增强的方法
  2. 切入点:实际被增强的方法
  3. 通知(增强):实际增强的逻辑部分
  4. 切面:是动作,把通知应用到切入点的过程

(2)使用方法

  1. 开启组件扫描(@ComponentScan),开启生成代理对象(@EnableAspectJAutoProxy(proxyTargetClass = true))
  2. 创建类,在类中写主干逻辑
  3. 创建增强类,编写增强逻辑,在类上加@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("增强的逻辑");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++并发编程指南07

文章目录 [TOC]5.1 内存模型5.1.1 对象和内存位置图5.1 分解一个 struct&#xff0c;展示不同对象的内存位置 5.1.2 对象、内存位置和并发5.1.3 修改顺序示例代码 5.2 原子操作和原子类型5.2.1 标准原子类型标准库中的原子类型特殊的原子类型备选名称内存顺序参数 5.2.2 std::a…

智慧园区如何融合五大技术实现全方位智能管理与服务创新

内容概要 在现代社会&#xff0c;智慧园区正逐渐成为管理与服务创新的风向标。以快鲸智慧园区管理系统为例&#xff0c;它为园区的数字化管理提供了一种全新的模式。该系统的核心在于如何充分应用物联网技术&#xff0c;自动化与信息化的结合&#xff0c;使得园区能够实现实时…

JxBrowser 7.41.7 版本发布啦!

JxBrowser 7.41.7 版本发布啦&#xff01; • 已更新 #Chromium 至更新版本 • 实施了多项质量改进 &#x1f517; 点击此处了解更多详情。 &#x1f193; 获取 30 天免费试用。

DeepSeek R1-Zero vs. R1:强化学习推理的技术突破与应用前景

&#x1f4cc; 引言&#xff1a;AI 推理的新时代 近年来&#xff0c;大语言模型&#xff08;LLM&#xff09; 的规模化扩展成为 AI 研究的主流方向。然而&#xff0c;LLM 的扩展是否真的能推动 通用人工智能&#xff08;AGI&#xff09; 的实现&#xff1f;DeepSeek 推出的 R1…

python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算

【0】基础定义 按位与运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;全1取1&#xff0c;其余取0。按位或运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;有1取1&#xff0c;其余取0。 按位取反运算&#xff1a;一个二进制数&#xff0c;0变1,1变0。 【1】…

第十四讲 JDBC数据库

1. 什么是JDBC JDBC&#xff08;Java Database Connectivity&#xff0c;Java数据库连接&#xff09;&#xff0c;它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库&#xff0c;并使用SQL语句来完成对数据库中数据的查询、新增、更新和删除等操作…

低代码系统-产品架构案例介绍、轻流(九)

轻流低代码产品定位为零代码产品&#xff0c;试图通过搭建来降低企业成本&#xff0c;提升业务上线效率。 依旧是从下至上&#xff0c;从左至右的顺序 名词概述运维层底层系统运维层&#xff0c;例如上线、部署等基础服务体系内置的系统能力&#xff0c;发消息、组织和权限是必…

第一届“启航杯”网络安全挑战赛WP

misc PvzHE 去这个文件夹 有一张图片 QHCTF{300cef31-68d9-4b72-b49d-a7802da481a5} QHCTF For Year 2025 攻防世界有一样的 080714212829302316092230 对应Q 以此类推 QHCTF{FUN} 请找出拍摄地所在位置 柳城 顺丰 forensics win01 这个软件 云沙盒分析一下 md5 ad4…

基于Python的人工智能患者风险评估预测模型构建与应用研究(上)

一、引言 1.1 研究目标与内容 本研究旨在运用 Python 语言,整合多种人工智能技术,构建高精度、高可靠性且具有良好可解释性的患者风险评估预测模型,为医疗领域的临床决策提供强有力的支持。具体研究内容涵盖以下几个方面: 人工智能技术在风险评估中的应用研究:深入剖析机…

unity学习24:场景scene相关生成,加载,卸载,加载进度,异步加载场景等

目录 1 场景数量 SceneManager.sceneCount 2 直接代码生成新场景 SceneManager.CreateScene 3 场景的加载 3.1 用代码加载场景&#xff0c;仍然build setting里先加入配置 3.2 卸载场景 SceneManager.UnloadSceneAsync(); 3.3 同步加载场景 SceneManager.LoadScene 3.3.…

每日一题——序列化二叉树

序列化二叉树 BM39 序列化二叉树题目描述序列化反序列化 示例示例1示例2 解题思路序列化过程反序列化过程 代码实现代码说明复杂度分析总结 BM39 序列化二叉树 题目描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。二叉树的序列化是将二叉树按照某种遍历方式…

Go学习:类型转换需注意的点 以及 类型别名

目录 1. 类型转换 2. 类型别名 1. 类型转换 在从前的学习中&#xff0c;知道布尔bool类型变量只有两种值true或false&#xff0c;C/C、Python、JAVA等编程语言中&#xff0c;如果将布尔类型bool变量转换为整型int变量&#xff0c;通常采用 “0为假&#xff0c;非0为真”的方…

CF 766A.Mahmoud and Longest Uncommon Subsequence(Java实现)

题目分析 (小何同学语文不太好&#xff0c;看这个题弯弯绕绕&#xff0c;看不懂一点&#xff0c;哈哈哈。)在尝试示例中分析之后&#xff0c;题目的意思大概就是&#xff0c;两个字符串相同就输出-1&#xff0c;不同就输出最长的那个字符串长度 思路分析 数据输入存值之后&…

大数据相关职位介绍之一(数据分析,数据开发,数据产品经理,数据运营)

大数据相关职位介绍之一 随着大数据、人工智能&#xff08;AI&#xff09;和机器学习的快速发展&#xff0c;数据分析与管理已经成为各行各业的重要组成部分。从互联网公司到传统行业的数字转型&#xff0c;数据相关职位在中国日益成为推动企业创新和提升竞争力的关键力量。以…

【力扣系列题目】最后一块石头的重量 分割回文串 验证回文串 等差数列划分{最大堆 背包 动态规划}

文章目录 七、最后一块石头的重量最后一块石头的重量【堆】[最后一块石头的重量 II](https://leetcode.cn/problems/last-stone-weight-ii/)【背包】 八、分割回文串分割回文串【分割子串方案数量】[分割回文串 II](https://leetcode.cn/problems/omKAoA/)【最少分割次数】[分割…

go gin配置air

一、依赖下载 安装最新&#xff0c;且在你工作区下进行安装&#xff0c;我的是D:/GO是我的工作区&#xff0c;所有项目都在目录下的src&#xff0c; go install github.com/air-verse/airlatest 如果出现类似报错&#xff1a; 将图中第三行 github.com/air-verse/air 替换最…

读书笔记--分布式服务架构对比及优势

本篇是在上一篇的基础上&#xff0c;主要对共享服务平台建设所依赖的分布式服务架构进行学习&#xff0c;主要记录和思考如下&#xff0c;供大家学习参考。随着企业各业务数字化转型工作的推进&#xff0c;之前在传统的单一系统&#xff08;或单体应用&#xff09;模式中&#…

openRv1126 AI算法部署实战之——ONNX模型部署实战

在RV1126开发板上部署ONNX算法&#xff0c;实时目标检测RTSP传输。视频演示地址 rv1126 yolov5 实时目标检测 rtsp传输_哔哩哔哩_bilibili 一、准备工作 1.从官网下载YOLOv5-v7.0工程&#xff08;YOLOv5的第7个版本&#xff09; 手动在线下载&#xff1a; Releases ultraly…

【C++题解】1055. 求满足条件的整数个数

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1055. 求满足条件的整数个数 类型&#xff1a;简单循环 题目描述&#xff1a; 在 1∼n 中&#xff0c;找出能同时满足用 3 除余 2 &#xff0c;用 5 除余 3 &#xff0c;用 7 除余…

亚博microros小车-原生ubuntu支持系列:17 gmapping

前置依赖 先看下亚博官网的介绍 Gmapping简介 gmapping只适用于单帧二维激光点数小于1440的点&#xff0c;如果单帧激光点数大于1440&#xff0c;那么就会出【[mapping-4] process has died】 这样的问题。 Gmapping是基于滤波SLAM框架的常用开源SLAM算法。 Gmapping基于RBp…