Spring框架学习-Spring的AOP概念详解
2024-08-27 15:58:11
一.SpringAOP的概述。
AOP(Aspect Oriented Programming),面向切面编程,通过预编译方式和运行期间动态代理实现程序的功能的统一维护的技术。AOP是OOP(面向对象编程)的扩展和延伸。举个例子,让大家对AOP印象更加深刻点。
比如权限校验。实际开发中,我们知道不是所有人都可以进行增删改查的操作,只有管理员才可以,所以我们需要在进行增删改查之前都需要进行权限校验。传统纵向继承(面向对象的特征)就是定义一个BaseDao,里面含有一个权限校验的方法,让Dao直接继承
BaseDao,这样就可以直接调用Dao父类中的权限校验方法。而AOP则采用的是横向抽取机制替代了传统的纵向继承,也就是通过生成代理的方式来解决。这就是对方法进行扩展的两个方法的思想。
AOP应用:权限校验,日志记录,性能监控(运用代理,分别在代码前后插入记录时间),事务控制
二.Spring底层实现AOP的原理。
底层用到了两种代理机制:
JDK动态代理:针对实现了接口的类的代理(java基础的代理)。
Cglib的动态代理:针对没有实现接口的类产生的代理,底层用的是字节码增强技术,通过生成当前类的子对象来产生代理。
被代理类
public class UserDaoImpl implements UserDao { @Override
public void insert() {
System.out.println("用户增加....");
} @Override
public void remove() {
System.out.println("用户移除....");
} }
JDK动态代理:
public class MyJDKProxy implements InvocationHandler {
// 定义属性,传入实现类对象,也可以不用,但是后面就要用类名,而不是引用
private UserDaoImpl userDao; public MyJDKProxy(UserDaoImpl userDao) {
this.userDao = userDao;
} // 创建UserDao动态代理
public UserDao createUserProxy() {
/*
* 第一个参数。告诉虚拟机用哪个字节码加载器加载内存创建字节码文件。
* 第二个参数。告诉虚拟机内存中创建的字节码文件中应该有哪个方法(这些方法方法体为空)。获取类的接口(类的方法可能增加,但接口的方法是固定的)
* 第三个参数。告诉虚拟机底层正在创建的字节码上的各个方法如何处理。
* */
UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(MyJDKProxy.class.getClassLoader(), userDao.getClass().getInterfaces(), this);
return userDaoProxy;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equalsIgnoreCase("insert")) {
System.out.println("权限校验");
}
// 执行被代理类原有的方法
return method.invoke(userDao, args);
} }
运行结构
权限校验
用户增加....
Cglib的父类:
public class CustDao { public void remove() {
System.out.println("顾客移除");
}
}
Cglib动态代理:
public class MyCglibProxy { public CustDao createProxy() {
// 创建cglib和心类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(CustDao.class);
// 设置回调
enhancer.setCallback(new MethodInterceptor() { @Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("remove".equalsIgnoreCase(method.getName())) {
// 执行被代理父类的方法
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("日志记录");
return obj;
}
return methodProxy.invokeSuper(proxy, args);
}
}); // 生成代理
CustDao custDao = (CustDao) enhancer.create();
return custDao;
}
}
运行结果:
权限校验
用户增加....
顾客移除
日志记录
最新文章
- github免输用户名/密码SSH登录的配置
- Scala 深入浅出实战经典 第45讲: scala中context bounds代码实例
- 携手K2 BPM,华住酒店完美实现“互联网+”转型
- marquee 笔记
- MFC中快速应用OpenCV教程
- 【Animations】
- java——Arrays.asList()方法
- CSS学习笔记四:下拉选择框以及其动画特效
- CodeForces - 1025C 字符串处理,画一个圆。。。
- 洛谷P3242 接水果
- SpringBoot乱码
- [Leetcode 62]机器人走路Unique Path 动态规划
- Angular2学习笔记(1)——Hello World
- css 初始包含块
- git报错:Pull is not possible because you have unmerged files解决方法
- HDU5139:Formula(找规律+离线处理)
- raw格式转换成qcow2格式
- python正则中如何匹配汉字以及encode(‘utf-8’)和decode(‘utf-8’)的互转
- java中int取值范围是怎么计算的?
- Android系统概述
热门文章
- java.lang.NoSuchMethodException: com.sun.proxy.$Proxy
- yolo原理学习
- 算法实现c语言--03
- SQL Server 2008将数据导出为脚本 [SQL Server]
- HDU 1394 树状数组+离散化求逆序数
- 3.javascript转换日期字符串为Date对象
- AngularJS系统学习之Factory,Service, Provider(工厂,服务,供应者)
- Java int与String互相转化大全
- 爬虫代码实现四:采用Hbase存储爬虫数据(1)
- springboot2 -广播式WebSocket