Spring 讲解(六)
如何理解 Spring 中的 AOP
一、AOP 的概述
AOP(Aspect Oriented Programming):面向切面编程,通过预编译方式和运行期动态代理来实现程序功能的统一维护的一种技术。
AOP是OOP(面向对象编程)的延续,是 Spring 框架中重要内容,是函数式编程的一种衍生范型。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
纵向继承。经典应用场景:事务管理、性能监视、安全检查、缓存 、日志等。
Spring AOP使用纯 Java 实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。
AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入。
Spring 中的 AOP 实现原理
a、接口 + 实现类 :Spring采用 jdk 的动态代理Proxy。
b、实现类:Spring 采用 cglib字节码增强。
a、Aop底层将采用代理机制进行实现(最底层也是依赖反射)。
二、AOP 实现案例
1、对 AOP 的理解(画图解释)

2、AOP 中通过 JDK动态代理简单案例演示
接口、实现类和切面类
public interface UserService {
void addUser();
void updateUser();
int deleteUser(int id);
}
=========================================================================================
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
@Override
public int deleteUser(int id) {
System.out.println("通过id删除用户");
return 1;
}
}
切面类
public class MyAspect {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("提交事务");
}
}
JDK实现动态代理
public class MyBeanFactory {
// JDK实现动态代理
public static UserService createUserService() {
//1.创建目标对象target
final UserService userService = new UserServiceImpl();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.把切面类2个方法应用于目标类
//3.1 创建JDK代理,拦截方法
UserService serviceProxy = (UserService) Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
(proxy, method, args) -> {
//开启事务
aspect.before();
//方法返回值:业务方法的返回值
Object retObj = method.invoke(userService, args);
//System.out.println("拦截返回值:" + retObj);
//提交事务
aspect.after();
return retObj;
}
);
return serviceProxy;
}
}
测试函数
public class AOPTest {
public static void main(String[] args) {
UserService userService = MyBeanFactory.createUserService();
userService.deleteUser(1);
userService.addUser();
userService.updateUser();
}
}
测试结果如下所示:
开启事务
通过id删除用户
提交事务
<=====================>
开启事务
添加用户
提交事务
<=====================>
开启事务
更新用户
提交事务
<=====================>
从测试结果可以看出,每次在执行业务代码的时候,会拦截对应的方法,执行切面类。
重点:JDK 的动态代理是通过接口和实现类完成的。
在 debug 测试函数: UserService userService = MyBeanFactory.createUserService();可以看出直接得到的是代理对象,代理对象中就有实现的功能。
在 debug 测试函数:UserService userService = new UserServiceImpl();可以看出直接得到的是其实现类,没有代理。
感兴趣的同学可以将测试函数中代码替换成上面两种。看看测试结果,以便于更好理解 AOP 思想。
3、AOP 中通过 CGlib 动态代理简单案例演示
public class StudentService {
void delete() {
System.out.println("删除用户");
}
void add() {
System.out.println("添加用户");
}
void update() {
System.out.println("更新用户");
}
}
public class MyBeanFactory {
// CGlib实现代理
public static StudentService createStudentService(){
//1.创建目标对象target
final StudentService studentService = new StudentService();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.创建增强对象
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(studentService.getClass());
//设置回调【拦截】
enhancer.setCallback((MethodInterceptor) (proxy, method, args, methodProxy) -> {
aspect.before();
Object retObj = methodProxy.invokeSuper(proxy,args);//解藕
System.out.println("拦截.....");
aspect.after();
return retObj;
});
//创建代理对象
StudentService serviceProxy = (StudentService) enhancer.create();
//System.out.println("serviceProxy);
return serviceProxy;
}
}
测试函数
public class AOPTest {
public static void main(String[] args) {
StudentService studentService = MyBeanFactory.createStudentService();
studentService.add();
System.out.println("<=====================>");
studentService.delete();
System.out.println("<=====================>");
studentService.update();
System.out.println("<=====================>");
}
}
测试结果如下所示:
开启事务
添加用户
拦截.....
提交事务
<=====================>
开启事务
删除用户
拦截.....
提交事务
<=====================>
开启事务
更新用户
拦截.....
提交事务
<=====================>
CGlib 代理重点总结
a、没有接口,只有实现类。
b、采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。
Spring 讲解(六)的更多相关文章
- Spring Boot(六):如何使用mybatis
Spring Boot(六):如何使用mybatis orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动 ...
- Spring第六篇【Spring AOP模块】
前言 Spring的第五篇也算是AOP编程的开山篇了,主要讲解了代理模式-..本博文主要讲解Spring的AOP模块:注解方式和XML方式实现AOP编程.切入点表达式.. AOP的概述 Aop: as ...
- Spring(十六)之MVC框架
MVC 框架教程 Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活.松散耦合的 web 应用程序的组件.MVC 模式导致了应用程序的不同方面(输入逻辑.业 ...
- Spring第六篇---AOP
接着Spring第五篇讲 我们今天将叙述以下几个知识点 1 什么是AOP AOP 是一种思想 横向重复 纵向抽取 在软件业,AOP为Aspect Oriented Programming的缩写,意 ...
- Spring Boot2(六):使用Spring Boot整合AOP面向切面编程
一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop aop全称Aspec ...
- spring讲解
今日先简单介绍一下Spring bean 的 5 种效果域,然后详细介绍 singleton 和 prototype 这两种最常用的效果域. JavaSpring Bean的五种效果域 效果域的种类 ...
- Spring讲解-----------表达式语言
转自:https://blog.csdn.net/u011225629/article/details/47143083 5.1 概述5.1.1 概述 Spring表达式语言全称为“S ...
- Spring 讲解(一 )
1.如何理解 Spring 框架 简单来说,Spring 是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. 因为以前写代码的时候,在使用类对象的时候,经常需要实例化创建(new 出来) ...
- spring boot(六):如何优雅的使用mybatis
*:first-child{margin-top: 0 !important}.markdown-body>*:last-child{margin-bottom: 0 !important}.m ...
随机推荐
- springboot上传excel到oss
参考:https://blog.csdn.net/qq_34864038/article/details/80239320 https://blog.csdn.net/qq_27319683/arti ...
- 51nod 1714:B君的游戏(博弈 sg打表)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1714 nim游戏的一个变形,需要打出sg函数的表 #incl ...
- Apache Flink 进阶(八):详解 Metrics 原理与实战
本文由 Apache Flink Contributor 刘彪分享,本文对两大问题进行了详细的介绍,即什么是 Metrics.如何使用 Metrics,并对 Metrics 监控实战进行解释说明. 什 ...
- 【HDU6609】Find the answer【线段树】
题目大意:给你一个序列,对于每个i,你可以选择1~i-1中任意多的数并将它删去,剩余的数(包括i)∑≤m,问对于每个i最少删几个数可以达到要求 题解: 考虑朴素的思想,对于每个i,我只需要删去最大的若 ...
- delphi String 与 Stream的互转
stream1 := TStringStream.create(str); str := TStringStream(stream1).DataString; Stream 是抽像类, ...
- 【python3】装饰器
参考文章: 理解Python装饰器(Decorator) 关键点: 写装饰器一定要搞定楚函数名后面带小括号和不带小括号的含义.带小括号,表示调用这个函数,而不带小括号,则表示的是该函数引用地址 简单装 ...
- 解决 ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'
原文链接:https://blog.csdn.net/sea_snow/article/details/82498791 感谢原作者大大 提示:ERROR 1044 (42000): Access ...
- 初识redis基础
一.redis 的五大数据类型: 1.String(字符串): 2.List(列表): 3.Set(集合): 4.Hash(哈希,类似于Java里的Map); 5.Zset(sorted set:有序 ...
- Cocos2d-x之数据的处理
| 版权声明:本文为博主原创文章,未经博主允许不得转载. FileUtils 在游戏中,用户要保存自己的偏好设置和玩家的信息,都需要涉及到游戏数据的处理.首先要想处理数据,则要找到文件,创建文件, ...
- “希希敬敬对”队软件工程第九次作业-beta冲刺第四次随笔
“希希敬敬对”队软件工程第九次作业-beta冲刺第四次随笔 队名: “希希敬敬对” 龙江腾(队长) 201810775001 杨希 201810812008 何敬 ...