Spring基于AOP(面向切面编程)开发

概述

        AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

为什么要学习AOP

在不修改源代码的情况下,对原方法进行增强

AOP可以校验,日志记录,性能监控,事务控制

底层实现(了解)

代理机制:

Spring的AOP的底层用到两种代理机制

        JDK动态代理:针对实现了接口的类产生的代理

        Cglib动态代理:针对没有接口的类产生的代理,应用了底层的字节码增强的技术,生成当前的子类对象

JDK动态代理

创建一个代理类

public class ProxyUser implements InvocationHandler {
	private Object target; // 代理的目标对象
	public LogJdkProxy(Object target) {
		this.target = target;
	}
	/** 创建代理对象 */
	public Object createProxyInstance() {
		// 第1个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
		// 第2个参数设置代理类实现的接口
		// 第3个参数设置回调对象,当代理对象的方法被调用时,会调用该参数指定对象的invoke方法
		return Proxy.newProxyInstance(//
				getClass().getClassLoader(), // 第1个参数
				target.getClass().getInterfaces(), // 第2个参数
				this); // 第3个参数
	}
	/**
	 * @param proxy  目标对象的代理类实例
	 * @param method 对应于在代理实例上调用接口方法的Method实例
	 * @param args   传入到代理实例上方法参数值的对象数组
	 * @return 方法的返回值,没有返回值(void)时是null
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("== Log:开始执行操作,方法名:"+method.getName()+" ==");
		Object result = method.invoke(target, args); // 执行原方法,把方法调用委派给目标对象
		System.out.println("== Log:操作执行完毕 ==");
		return result;
	}
}

测试

Cglib动态代理

创建对象接口

// 此类不能是final的,否则不能有子类,CGLIB也就不能工作了
public class UserServiceImpl {
 
	// 这是final的方法,不能被子类重写,所以CGLIB不会拦截这个方法
	public final void foo1() {
		System.out.println(">> final的方法 <<");
	}
 
	// 这是static的方法,CGLIB不会拦截这个方法
	public static void foo2() {
		System.out.println(">> static的方法 <<");
	}
 
	// 这是private的方法,CGLIB不会拦截这个方法
	private void foo3() {
		System.out.println(">> private的方法 <<");
	}
 
	// CGLIB会拦截这个方法,可以是public, protected, default的修饰符
	public void deleteUser() {
		System.out.println(">> 删除一个User <<");
	}
}

创建Cglib代理类

// CGLIB代理类
public class LogCglibProxy implements MethodInterceptor {
	private Object target; // 代理的目标对象
	/**
	 * 创建代理对象
	 * @param <T>
	 * @param target 目标对象
	 */
	public <T> T createProxyInstance(T target) {
		this.target = target;
		Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象
		enhancer.setSuperclass(target.getClass()); // 设置父类
		enhancer.setCallback(this); // 设置回调对象为自己这个对象
		return (T) enhancer.create(); // 创建代理对象并返回
	}
	/**
	 * @param proxy 		 目标对象代理类的实例
	 * @param method		代理类实例上调用父类方法的Method实例
	 * @param args 			传入到方法参数值的对象数组
	 * @param methodProxy 	使用它调用父类的方法
	 */
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, 
MethodProxy methodProxy)	throws Throwable {
		System.out.println(proxy.getClass());
		System.out.println("== Log:开始执行操作,方法名:" + method.getName() + " ==");
		Object result = methodProxy.invoke(target, args); // 执行原方法
		System.out.println("== Log:操作执行完毕 ==");
		return result;
	}
}

测试

public class MainTest {

	@Test
	public void test() throws Exception {
		UserService userService = new UserService();
		userService = (UserService) new LogCglibProxy().createProxyInstance(userService); // 使用包装之的后的代理对象

		userService.saveUser();
		System.out.println();

		userService.deleteUser();
		System.out.println();
}
}

Spring使用AspectJ进行AOP开发

引入lib包

引入配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
使用xml配置文件形式

通知类型

切入点表达式

编写一个切面类

public class MyAspectXml {
// 前置增强
public void before(){
System.out.println("前置增强===========");
    }
}

在application Context.xml中配置

<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.test.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut expression="execution(* cn.test.spring.demo3.OrderDao.save(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1"/> </aop:aspect>
</aop:config>
使用注解来实现切面类

开启aop注解自动代理

AspectJ的AOP注解

@Aspect  定义切面类

通知类型

@Before        前置通知

@AfterReturing        后置通知

@Around        环绕通知

@After        最终通知

@AfterThrowing        异常抛出通知

@Pointcut        定义切入点

编写切面类

@Component
@Aspect
public class MyAspect {
    @Before("MyAspect.pointcut01()")
    public void before(){
        System.out.println("前置-----");
    }

    @After("MyAspect.pointcut01()")
    public void after(){
        System.out.println("后置-----");
    }
    @Pointcut("execution(* com.xuexi.dao.*.*(..))")
    public void pointcut01(){

    }
}

测试

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通过旋转机械臂,将机械臂上相机拍摄图像的任意点移动至图像中心的方法

计算原理 角度计算 相机CCD大小固定&#xff0c;即相机成像平面大小固定&#xff0c;相机视场角(FOV)仅由相机焦距F决定&#xff1b; 因此&#xff0c;定焦相机的FOV大小固定&#xff0c;通过上图可以看出相机视场角的计算公式为&#xff1a; FOV 2*atan&#xff08;w/2f&…

Windows 下 使用 VSCode 和 arm-none-eabi 编译Linux代码时 mkdir 命令出错

编译环境&#xff1a; IDE: VSCode 交叉编译器&#xff1a;arm-none-eabi make 命令&#xff1a;Mingw-w64 GCC for Windows 64 源代码管理&#xff1a;git 交叉编译器版本和安装目录: E:\work_soft\gcc-arm-none-eabi-10.3-2021.10 Mingw 版本和目录&#xff1a;E:\work_…

C++ 设计模式之外观模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是外观模式 外观模式Facade Pattern , 也被称为“⻔⾯模式”&#xff0c;是⼀种结构型设计模式&#…

2011 年考研数二真题解析

一、选择题 【01】【02】【03】【04】【05】【06】【07】【08】 二、填空题 【09】【10】【11】【12】【13】【14】 三、解答题 【15】【16】【17】【18】【19】【20】【21】【22】【23】

Vue高级(二)

3.搭建vuex环境 创建文件&#xff1a;src/store/index.js //引入Vue核心库import Vue from vue//引入Vueximport Vuex from vuex//应用Vuex插件Vue.use(Vuex)//准备actions对象——响应组件中用户的动作const actions {}//准备mutations对象——修改state中的数据const mutat…

mac idea 配置docker 插件

mac默认配置 会报错 mac Can’t connect: com.intellij.docker.agent.Api TaskException: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (Details: [2] No such file or directory) 终端执行 sudo ln -s "$HO…

中学生英语杂志中学生英语杂志社中学生英语编辑部2023年第46期目录

“《中学生英语》教育教改与考试研究中心”课题组课题成果交流 高中英语学习动机因素与其对学习成效的影响研究 仇丽; 3-4 主位推进程序在高中英语读后续写中的应用 陈媛媛; 5-6《中学生英语》投稿&#xff1a;cn7kantougao163.com 小学英语教学:互动式英语词汇记忆…

Spring AOP 源码分析

【阅读前提】&#xff1a; 需了解AOP注解开发流程&#xff1a;链接 一、注解 EnableAspectJAutoProxy 在配置类中添加注解EnableAspectJAutoProxy&#xff0c;便开启了AOP&#xff08;面向切面编程&#xff09; 功能。此注解也是了解AOP源码的入口。 EnableAspectJAutoProxy…

外贸建站服务器如何选?海洋建站主机推荐?

外贸建站用哪个服务器比较好&#xff1f;独立网站怎么选择主机&#xff1f; 随着全球化的趋势&#xff0c;外贸网站的建设越来越受到企业的重视。然而&#xff0c;要想让外贸网站稳定、安全、可靠地运行&#xff0c;选择合适的外贸建站服务器是关键。海洋建站将详细介绍如何选…

Git 实操

文章目录 安装本地操作工作流程 Git 初始化以及仓库的创建、操作基本信息初始化一个Git 仓库 Git 管理远程仓库Git 克隆给远程仓库设置别名pull 拉取并合并分支Push推送到远程实战 git 是免费的管理github 的一个软件 安装 Git 官网下载&#xff1a;https://git-scm.com/downlo…

前端(二)VUE功能集锦

一、引言 作者开发工具平台的时候&#xff0c;用到了vue和element-ui&#xff0c;这里写一下各种功能使用&#xff0c;有的是绕点弯路&#xff0c;有的是需要结合实现需要自己改写一下。 二、功能 先看看环境&#xff0c;作者后端是SpringBoot&#xff0c;前端是VUEElementUI&a…

揭秘高生产力设计工具!15款原型设计软件推荐大公开!

1、Proto.io Proto.io是一个特殊的手机原型开发平台——可以构建和部署全交互式移动程序的原型&#xff0c;并可以模拟类似的成品。它可以在大多数浏览器中运行&#xff0c;并提供三个重要的界面&#xff1a;dashboard、编辑器和播放器。 dashboard可以用来管理项目。编辑器是…

spring常见漏洞(3)

CVE-2017-8046 Spring-Data-REST-RCE(CVE-2017-8046)&#xff0c;Spring Data REST对PATCH方法处理不当&#xff0c;导致攻击者能够利用JSON数据造成RCE。本质还是因为spring的SPEL解析导致的RCE 影响版本 Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3 Spring Bo…

亚信安慧AntDB数据库自主研发技术再获国际认可

亚信安慧AntDB数据库最新宣布喜讯&#xff1a;成功通过了GB 18030-2022《信息技术 中文编码字符集》的最高级别认证&#xff0c;从而荣幸地成为首批获得此认证的数据库产品之一。这一认证的取得不仅是AntDB在技术上的重要里程碑&#xff0c;更是对其一贯积极践行国家政策和标准…

护眼台灯哪个品牌更好?汇总好用的护眼台灯前五名

随着对健康生活的追求不断增长&#xff0c;越来越多的人开始关注眼睛健康问题。在日常生活和工作中&#xff0c;台灯作为常用的照明设备之一备受关注&#xff0c;尤其是护眼台灯的问世引起了广泛关注。尤其是对于那些经常长时间用眼的人群&#xff0c;比如面临较重课业负担的学…

转载 | 深耕数据安全 创新“智”高点-天空卫士获评金智奖“年度最具影响力企业奖”

近日&#xff0c;以“并肩聚力&#xff0c;协同创新&#xff0c;共谋网络安全产业新发展”为主题的2022-2023年度中国网络安全与信息产业“金智奖”颁奖盛典在上海隆重举行。北京天空卫士网络安全技术有限公司&#xff08;以下简称“天空卫士”&#xff09;凭借其高速成长能力、…

【书生·浦语】大模型实战营——第五次课程作业

基础作业——使用LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署InternLM-Chat-7B模型&#xff0c;生成300字的小故事 环境准备 除了安装所需依赖之后&#xff0c;重要的是进行模型转化&#xff08;转换成TurboMind格式&#xff09;&#xff0c;这里需要注意转化命…

Android项目架构怎么做

项目架构指南 本指南包含一些最佳做法和推荐架构&#xff0c;有助于构建强大而优质的应用。 注意&#xff1a; 本页假定您对 Android 框架有基本的了解。 移动应用用户体验 典型的 Android 应用包含多个应用组件&#xff0c;包括 Activity、Fragment、Service、内容提供程序…

计算机毕业设计----SSH滑雪场场地租赁管理系统

项目介绍 该项目主要包括三个角色&#xff1a;管理员、收银员、用户&#xff1b; 用户角色包含以下功能&#xff1a; 用户登录,修改个人信息,查看我的订单等功能。 管理员角色包含以下功能&#xff1a; 管理员登录,滑雪场管理,订单管理,教练管理,器材管理,会员管理,收银员管…

docker容器和常用命令

1.什么是容器 容器是隔离的环境中运行的一个 进程 , 如果进程结束 , 容器就会停止. 细致: 容器的隔离环境 , 拥有自己的 ip 地址 , 系统文件 , 主机名 , 进程管理 , 相当于一个 mini的系统 2.容器 vs 虚拟机 3.Docker极速上手指南 #1.安装相关依赖. sudo yum install -y …