移动端touch拖动事件和click事件冲突问题解决

news2024/11/26 3:37:57

通过本课程你会学到什么

1.系统掌握 Web 全栈技能树
2.网络、前后端、持久化等核心技术解析
3.全栈开发的技术比较和选型
4.拓宽技术视野,培养全栈思维


今天我们要接触一个和 MVC 密切相关的,能带来思维模式改变的编程范型——面向切面编程(AOP,Aspect Oriented Programming)

给我一把锤子,满世界都是钉子

我记得曾经有这样一个相当流行的观点,是说,编程语言只需要学习一门就够了,学那么多也没有用,因为技术是一通百通的,别的编程语言可以说是大同小异。我相信至今抱有这种观点的程序员也不在少数。

可惜,事实远没有那么美好。这个观点主要有两处值得商榷:

  • 其一,不同的技术,在一定程度上确实是相通的,可是,技术之间的关联性,远不是“一通百通”这四个简简单单的字能够解释的。妄想仅仅凭借精通一门编程语言,就能够自动打通其它所有编程语言的任督二脉,这是不现实的。* 其二,通常来说,说编程语言大同小异其实是很不客观的。编程语言经过了长时间的发展演化,如今已经发展出非常多的类型,用作编程语言分类标准之一的编程范型也可谓是百花齐放。因此我们要学习多种编程语言,特别是那些能带来新的思维模式的编程语言。现在,把这个观点泛化到普遍的软件技术上,也一样适用。我们都知道要“一切从实际出发”,都知道要“具体问题具体分析”,可是,在眼界还不够开阔的时候,特别是职业生涯的早期,程序员在武器库里的武器还非常有限的时候,依然无法避免“给我一把锤子,满世界都是钉子”,在技术选择的时候眼光相对局限

所以我们要学习全栈技术,尤其是要学习这些不一样,但一定层面上和已掌握知识相通的典型技术。今天我们要学习的这项在 MVC 框架中广泛使用的技术,是和面向对象编程一类层面的编程范型,叫做面向切面编程。

互联网有许多功能,如果使用传统的基于单个请求处理流程的方式来编码,代码就会非常繁琐,而使用 AOP 的方式,代码可以得到很大程度上的简化。希望通过今天的学习,你的武器库里,能够多一把重型机枪。

AOP 的概念

面向切面编程是一种通过横切关注点(Cross-cutting Concerns)分离来增强代码模块性的方法,它能够在不修改业务主体代码的情况下,对它添加额外的行为。

不好理解吗?没关系,我们来对它做进一步的说明。

首先需要明确的是,AOP 的目标是增强代码模块性,也就是说,本质上它是一种“解耦”的方法,在这方面它和我们之前介绍的分层等方法是类似的,可是,它分离代码的角度与我们传统、自然的模块设计思路截然不同。

我们来看下面这样一个例子,对于图书馆系统来说,有许多业务流程,其中借书和还书是最典型的两条。对于这些业务流程来说,从图书系统接收到请求开始,需要完成若干个步骤,但这些步骤都有一些“共性”,比如鉴权,比如事务控制:

那么,如果我们按照自然的思考方式,我们会把代码按照流程分解成一个一个的步骤,在每个步骤完成的前后添加这些“共性”逻辑。可是这样,这些逻辑就会散落在代码各处了,即便我们把它们按照重复代码抽取的原则,抽出来放到单独的方法中,这样的方法的“调用”还是散落在各处,无论是对软件工程上的可维护性,还是代码阅读时对于业务流程的专注度,都是不利的。

藉由 AOP 则可以有效地解决这些问题,对于图中横向的业务流程,我们能够保持它们独立不变,而把鉴权、事务这样的公共功能,彻底拿出去,放到单独的地方,这样整个业务流程就变得纯粹和干净,没有任何代码残留的痕迹,就好像武林高手彻底隐形了一般,但是,功能却没有任何丢失。就好比面条一般顺下来的业务流程,水平地切了几刀,每一刀,都是一个 AOP 的功能实现。

我们可能在 Java 的世界中谈论 AOP 比较多,但请注意,它并不是 Java 范畴的概念,它不依赖于任何框架,也和编程语言本身无关。

Spring 中的应用

Spring 作为一个应用程序框架,提供了对于 AOP 功能上完整的支持,下面让我们通过例子来学习

public class BookService {

 public Book lendOut(String bookId, String userId, Date date) { ... (0) }

} 

现在,我们要给很多的业务方法以 AOP 的方式添加功能,而 lendOut 就是其中之一。定义一个 TransactionAspect 类:

public class TransactionAspect {public void doBefore(JoinPoint jp) { ... (1) }public void doAfter(JoinPoint jp) { ... (2) }public void doThrowing(JoinPoint jp, Throwable ex) { ... (3) }public void doAround(ProceedingJoinPoint pjp) throws Throwable { ... (4)pjp.proceed();... (5)} 
} 

你看,我给每一处可以实现的代码都用数字做了标记。我们希望在 doBefore 方法中添加事务开始逻辑,doAfter 方法中添加事务结束的提交逻辑,doThrowing 方法中添加事务失败的回滚逻辑,而在 doAround 方法中业务执行前后添加日志打印逻辑,其中的 pjp.proceed() 方法表示对原方法的调用。

接着,我们需要写一些 XML 配置,目的就是把原方法和 AOP 的切面功能连接起来。配置片段如下:

<bean id="bookService" class="xxx.BookService"></bean>
<bean id="transactionAspect" class="xxx.TransactionAspect"></bean>
<aop:config><aop:pointcut expression="execution(* xxx.BookService.*(..))" id="transactionPointcut<aop:aspect ref="transactionAspect"><aop:before method="doBefore" pointcut-ref="transactionPointcut"/><aop:after-returning method="doAfter" pointcut-ref="transactionPointcut"/><aop:after-throwing method="doThrowing" pointcut-ref="transactionPointcut" throwing=<aop:around method="doAround" pointcut-ref="transactionPointcut"/></aop:aspect>
 </aop: config> 

在这段配置中,前两行分别是对 BookService 和 TransactionAspect 这两个 Bean 的声明,接下来在 aop:config 中,我们定义了 pointcut 的切面匹配表达式,表示要捕获 BookService 的所有方法,并在 aop:aspect 标签内定义了我们希望实施的 AOP 功能。

在实际执行的过程中,如果没有异常抛出,上述这些逻辑的执行顺序将是:

(1) → (4) → (0) → (5) → (2) 

实现原理

讲了 AOP 怎样配置,怎么表现,现在我要来讲讲它的实现原理了。通过这部分内容,希望你可以搞清楚,为什么不需要对代码做任何改动,就可以在业务逻辑的流水中切一刀,插入我们想要执行的其它逻辑呢?

对于常见的实现,我们根据其作用的不同时间阶段进行分类,有这样两种:

编译期间的静态织入,又称为编译时增强。织入(Weaving),指的是将切面代码和源业务代码链接起来的过程。AspectJ 就是这样一个面向切面的 Java 语言扩展,称呼其为语言的“扩展”,就是因为它扩展了 Java 语言的语法,需要特定的编译器来把 AspectJ 的代码编译成 JVM 可识别的 class 文件。

运行期间的动态代理,又称为运行时增强。这种方式是在程序运行时,依靠预先创建或运行时创建的代理类来完成切面功能的。比如 JDK 基于接口的动态代理技术,或 CGLib 基于类的代理对象生成技术就属于这一种。

Spring AOP 默认支持的是后者——运行期间的动态代理。至于具体实现,通常来说,我们应该优先考虑使用 JDK 的动态代理技术;但是如果目标类没有实现接口,我们只能退而求其次,使用 CGLib。

动态代理的方式由于在运行时完成代理类或代理对象的创建,需要用到 Java 的拦截、反射和字节码生成等技术,因此运行时的性能表现往往没有静态织入好,功能也有较多限制,但是由于使用起来简便(不需要语言扩展,不需要特殊的编译器等),它的实际应用更为广泛。

控制反转 IoC

通过 AOP 我们知道,某些问题如果我们换个角度来解决,会很大程度地简化代码。现在,让我们来了解在 Spring 中另一个经常和面向切面编程一起出现的概念——控制反转。控制反转是一种设计思想,也是通过“换个角度”来解决问题的。

控制反转,IoC,即 Inversion of Control,言下之意,指的是把原有的控制方向掉转过来了。在我们常规的程序流程中,对象是由主程序流程创建的,例如,在业务流程中使用 new 关键字来创建依赖对象。

但是,当我们使用 Spring 框架的时候,Spring 把对象创建的工作接管过来,它作为对象容器,来负责对象的查找、匹配、创建、装配,依赖管理,等等。而主程序流程,则不用关心对象是怎么来的,只需要使用对象就可以了。我们还是拿 BookService 举例子:

public class BookService { @Autowired private BookDao bookDao; @Autowired private LoanDao loanDao; public Book lendOut(String bookId, String userId, Date date) { bookDao.update( ... ); loanDao.insert( ... ); }

 } 

比如 BookService 的借出方法,假如它的实现中,我们希望:

  • 调用数据访问对象 bookDao 的方法来更新被借书的状态;* 调用借阅行为的访问对象 loanDao 来增加一条借阅记录。在这种情况下,我们可以通过 @Autowired 注解,让容器将实际的数据访问对象注入进来,主程序流程不用关心“下一层”的数据访问对象到底是怎么创建的,怎么初始化的,甚至是怎么注入进来的,而是直接用就可以了,因为这些对象都已经被 Spring 管理起来了。

如果这些注入的对象之间还存在依赖关系,初始化它们的顺序就至关重要了,可是在这种情况下,Service 层依然不用关心,因为 Spring 已经根据代码或配置中声明的依赖关系自动确定了。总之,Service 层的业务代码,只管调用其下的数据访问层的方法就好了。

读到这里,你可能会回想起前文 AOP 的内容,和 IoC 似乎有一个共同的特点:都是为了尽可能保证主流程的纯粹和简洁,而将这些不影响主流程的逻辑拿出去,只不过这两种技术,“拿出去”的是不同的逻辑。值得注意的是,对象之间的依赖关系,各层之间的依赖关系,并没有因为 IoC 而发生任何的改变。

IoC 在实现上包含两种方式,一种叫做依赖查找(DL,Dependency Lookup),另一种叫做依赖注入(DI,Dependency Injection)。二者缺一不可,Spring 容器做到了两者,就如同上面的例子,容器需要先查找到 bookDao 和 loanDao 所对应的对象,再把它们注入进来。当然,我们平时听到的更多是第二种。

有了一个大致的感受,那么 IoC 到底能带来什么好处呢?我觉得主要有这样两个方面:

  • 资源统一配置管理。这个方面很好,但并不是 IoC 最大的优势,因为,如果你不把资源交给容器管理,而是自己建立一个资源管理类来管理某项资源,一样可以得到“统一管理”的所有优势。* 业务代码不再包含依赖资源的访问逻辑,因此资源访问和业务流程的代码解耦开了。我觉得这里的“解耦”才是 IoC 最核心的优势,它让各层之间的依赖关系变得松散。就如同上面的代码例子一样,如果哪一天我想把它依赖的 bookDao 和 loanDao 替换掉(比如,我想为 Service 层做测试),Service 一行代码都不用改,它压根都不需要知道。* * *

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

OpenCV StudyNote

Open CV学习 图像读取与显示 灰度图像 - 单通道 彩色图像 - 三通道 (B, G, R) 一般步骤 import cv2 as cv # 导入OpenCV支持(cv2是包的名称不是版本号) import numpy as np # 所有图像数据都是以 numpy 数组方式存储 imread(filename[,flags]) # imread 函数&am…

自助服务:怎么提高客服人员效率?

越来越多的企业意识到了客服效率的重要性&#xff0c;大家通过布局全渠道系统、智能客服机器人、人员岗前培训等方式来提升客服效率&#xff0c;为客户提供更迅速、专业、优质的服务。人员效率的提升不仅能提高客户体验&#xff0c;还有助于企业的长期发展&#xff0c;带来更多…

【Vue2+Element ui通用后台】头部

文章目录headerheader 在 components 中新建 CommonHeader.vue 组件来完成头部组件的编写 <template><div class"header-container"><div class"l-content"><el-button icon"el-icon-menu" size"mini"><…

【MySQL】索引基础介绍

一、常见的存储引擎有哪些&#xff1f;区别是什么&#xff1f; Mysql 默认的存储引擎是&#xff1a;InnoDB&#xff0c;具有支持事务、行级锁、高并发访问性能。MyIsAM&#xff1a;访问速度快&#xff0c;实际运用如果是以读和插入操作为主&#xff0c;并对事物完整性和并发性…

面向对象程序设计期末项目总结

面向对象程序设计期末项目总结 开发前准备 MysqlNavicatTomCatIDEA 一&#xff0c;配置项目环境 右键项目名&#xff0c;添加新模块 命名后右键新建的模块 选中Web模块 到此项目创建完毕&#xff0c;接下来是配置环境。 打开IDEA–>File找到Project Structure 添加所…

Pikachu(皮卡丘)靶场中SQL注入

Pikachu靶场中SQL注入1.Pikachu(皮卡丘)靶场中SQL注入1.1.数字型注入1.2.字符型注入1.3.搜索型注入1.4.xx型注入1.5.insert/update注入1.6.delete注入1.7.http头注入1.8.盲注(base on boolian)1.9.盲注(base on time)1.10.宽字节注入1.Pikachu(皮卡丘)靶场中SQL注入 若遇到不链…

基于java+springboot+mybatis+vue+mysql的冬奥会科普平台

项目介绍 基于SpringBoot框架的冬奥会科普平台利用网络沟通、计算机信息存储管理&#xff0c;有着与传统的方式所无法替代的优点&#xff0c;系统采用java语言开发&#xff0c;前端采用vue技术&#xff0c;数据库采用mysql进行数据存储。比如计算检索速度特别快、可靠性特别高…

大数据如何在制造业中进行应用?数据宝董事长汤寒林现身数字化年会讲了这个事

12月8日1670923102263472480日&#xff0c;2022中国数字化年会成功在线上举办&#xff01;本届年会以“向变而生”为主题&#xff0c;历时三天&#xff0c;特别打造了主论坛、高峰论坛与行业数智化论坛三大板块&#xff0c;60余位专家学者与来自各领域各行业数字化领军人物 通过…

前端基础(五)_CSS文本文字属性

CSS文本文字属性 1、文字属性 1.1、字号 font-size&#xff1a;38px; 浏览器默认16px; 1.2、字体 font-family: 如果字体名称包含空格&#xff0c;字体名称上加引号&#xff1b; 中文字体名称加引号&#xff1b; 多个字体名称作为一个回退系统来保存&#xff0c;如果第一个不…

什么才是写博客初心如何坚持

为何写机器人课程博客并一直坚持&#xff1f;&#xff08;2021&#xff09; 创新源自真心&#xff0c;“乱”创新的课程徒有其表&#xff0c;“不”创新的课程逐渐凋零。 个人觉得&#xff0c;课程教学创新宏观上的目标是让学生更好的认识自己并适应社会发展和变化&#xff1b…

停车场管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 主要用jsp,数据库用MySQL 分为前台用户和后台管理员 前台用户 主界面是一个区域内的两到三个停车场&#xff0c;然后 可…

virtualenv系列 (2) · 系统环境与虚拟环境

文章目录1. 怎样算是一套Python环境&#xff1f;2. 系统环境 VS 虚拟环境3. 虚拟环境最佳实践1. 怎样算是一套Python环境&#xff1f; 首先&#xff0c;我们得先弄清楚&#xff1a;怎样算是一个Python环境&#xff1f;然后再去区分系统环境和虚拟环境。简单地说&#xff0c;在…

[附源码]Python计算机毕业设计SSM基于web的家教管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

阿里5位高级架构师耗时两年共同研发《Redis入门手册》

在我们日常的开发中&#xff0c;无不都是使用数据库来进行数据的存储&#xff0c;由于一般的系统任务中通常不会存在高并发的情况&#xff0c;所以这样看起来并没有什么问题&#xff0c;可是一旦涉及大数据量的需求&#xff0c;比如一些商品抢购的情景&#xff0c;或者是主页访…

喜报!Coremail两大方案入选“2022年软件行业典型应用案例”

12月5日&#xff0c;由中国软件行业协会联合中软国际有限公司、江苏省软件行业协会主办的2022中国程序员节在江苏南京圆满落幕&#xff0c;本次活动聚焦当前我国对数字技术创新及应用发展的现实需求&#xff0c;以开源创新、软件根技术、平台工具等热点议题&#xff0c;探讨影响…

Spring Boot 配置文件 · properties 基本语法 · yml 基本语法 · yml 配置不同数据以及 null · yml 配置文件读取

一、配置文件作用二、配置文件的格式三、properties 配置文件说明3.1 properties 基本语法3.2 读取配置文件3.3 properties 缺点分析四、yml 配置文件说明4.1 yml 基本语法4.2 yml 与 properties 格式对比4.3 yml 配置不同数据类型以及 null4.4 yml 配置读取4.4.1 读取配置文件…

Win11十二月系统更新了什么内容?

微软今天发布了12月最新的累积更新补丁&#xff0c;根据Microsoft 支持页面&#xff0c;build 22621.963 现在会在用户 OneDrive 上的存储空间不足时在“设置”应用程序中警告用户&#xff0c;将 Windows Spotlight 与主题设置相结合&#xff0c;修复任务管理器应用程序的界面问…

SSM垃圾分类网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 1,系统&#xff1a;Vindows10 2.软件&#xff1a;IDEA.SQLyog 3.数据库环境&#xff1a;ySQL 4.开源框架&#xff1a;sp…

毕业设计-基于SpringBoot幼儿园管理系统

环境&#xff1a;开发工具&#xff1a;idea&#xff0c;数据库&#xff1a;MySQL5.7 jdk1.8 架构&#xff1a;SpringBoot&#xff0c;前端HTML 主要功能 管理员&#xff1a; 用户管理&#xff08;编辑用户、删除用户、添加用户、查询指定用户&#xff09; 角色管理&#xff08;…

软件测试进阶——测试划分

文章目录按照测试对象划分界面测试可靠性测试容错性测试文档测试兼容性测试易用性测试安装和卸载测试安全测试性能测试按照是否查看代码黑盒测试白盒测试灰盒测试按照开发阶段划分单元测试集成测试系统测试回归测试冒烟测试验收测试按照实施组织划分α测试β测试按照是否运行划…