知识点-SpringAOP_盐仓的博客-程序员资料

技术标签: 笔记  aop  

转自:微信公众号-Java帮帮-20190118

Spring AOP是什么?

我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限验证、事务等功能时,只能在在每个对象里引用公共行为。这种方式不利于长期维护,且会造成大量重复代码,AOP就可以来弥补OOP的不足,

  1. 代理模式

比如A对象要做一件事情,在没有代理前,自己来做;在对 A 代理后,由 A 的代理类 B 来做。代理其实是在原实例前后加了一层处理,这也是 AOP 的初级轮廓。

  1. 静态代理原理及实践

静态代理就是在程序运行前就已经存在代理类的字节码文件、代理类和原始类的关系在运行前就已经确定
比如:

// 接口
public interface IUserDao {
void save();
void find();
}

// 目标对象
class UserDao implements IUserDao{
@Override
public void save() {
System.out.println(“模拟:保存用户!”);
}
@Override
public void find() {
System.out.println(“模拟:查询用户”);
}
}

/**
*静态代理
*/
class UserDaoProxy implements IUserDao{
// 代理对象,需要维护一个目标对象
private IUserDao target = new UserDao();
@Override
public void save() {
System.out.println(“代理操作: 开启事务…”);
target.save(); // 执行目标对象的方法
System.out.println(“代理操作:提交事务…”);
}
@Override
public void find() {
target.find();
}
}
特点:目标对象必须实现接口、 代理对象要和目标对象实现一样的接口

静态代理保证了业务类只关注逻辑本身,代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,就需要为每一种方法都进行代理,而且如果要增加一个方法,除了实现类需要实现这个方法,所有的代理类也要实现此方法。

  1. 动态代理
    动态代理的源码是在程序运行期间,通过JVM反射等机制动态生成,代理类和委托类是关系是在运行时才确定的。

// 接口
public interface IUserDao {
void save();
void find();
}

//目标对象
class UserDao implements IUserDao{
@Override
public void save() {
System.out.println(“模拟: 保存用户!”);
}
@Override
public void find() {
System.out.println(“查询”);
}
}

动态代理:代理工厂,给多个目标对象生成代理对象!

class ProxyFactory{

// 接收一个目标对象
private Object target;

public ProxyFactory(Object target) {
    this.target = target;
}

// 返回对目标对象(target)代理后的对象(proxy)
public Object getProxyInstance() {
    Object proxy = Proxy.newProxyInstance(
        target.getClass().getClassLoader(),  // 目标对象使用的类加载器
        target.getClass().getInterfaces(),   // 目标对象实现的所有接口
        new InvocationHandler() {            // 执行代理对象方法时候触发

            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {

                // 获取当前执行的方法的方法名
                String methodName = method.getName();
                // 方法返回值
                Object result = null;
                if ("find".equals(methodName)) {
                    // 直接调用目标对象方法
                    result = method.invoke(target, args);
                } else {
                    System.out.println("开启事务...");
                    // 执行目标对象方法
                    result = method.invoke(target, args);
                    System.out.println("提交事务...");
                }
                return result;
            }
        }
    );
    return proxy;
}
}

动态代理(动态代理也叫JDK代理或接口代理)
IUserDao proxy = (IUserDao)new ProxyFactory(target).getProxyInstance();
其实是 JDK 动态生成了一个类去实现接口,隐藏了这个过程:
class $jdkProxy implements IUserDao{}
使用 JDK 生成的动态代理的前提是目标类必须有实现的接口。但这里又引入一个问题,如果某个类没有实现接口,就不能使用 JDK 动态代理。所以 CGLIB 代理就是解决这个问题的。

CGLIB 是以动态生成的子类继承目标的方式实现,在运行期动态的在内存中构建一个子类,如下:

public class UserDao{}
// CGLIB 是以动态生成的子类继承目标的方式实现,程序执行时,隐藏了下面的过程
public class $Cglib_Proxy_class extends UserDao{}
CGLIB 使用的前提是目标类不能为 final 修饰。因为 final 修饰的类不能被继承。

现在,我们可以看看 AOP 的定义:面向切面编程,核心原理是使用动态代理模式在方法执行前后或出现异常时加入相关逻辑。

通过定义和前面代码我们可以发现3点:

AOP 是基于动态代理模式。
AOP 是方法级别的。
AOP 可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45386328/article/details/109185702

智能推荐

android studio 4.1.1 创建的Kotlon项目无法直接使xml的ID_qq_29254653的博客-程序员资料

在B站上学习 Android零基础教程(Kotlin)——手把手教开发今日头条在学习mvp架构搭建时 up主的说 kotlin能直接使用xml中的id,我实操时发现无法直接使用###解决方法:在对应的module配置文件中加上如下代码即可plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // 加上这段配置即可}...

当面试官问你有什么想问的应该问些什么(技术开发类)_潇潇凤儿的博客-程序员资料

找了大概一个多月的工作了,手头现在有满意的offer了,可以开始总结自己面试过程中遇到的一些问题及自己是怎么回答的,给即将要面试或是将来要面试的同学们一些参考吧。这篇主要说说在面试官面完自己后,自己有什么要问面试官的,这个一般跟最终面试结果关系不大,但是也可以稍微准备下,不至于到时现场想,或者直接说没有什么问题。要不面试官觉得你对此岗位或是他们公司一点兴趣都没有。 下面分别就一面...

VSTO打包加载项 WPS可用 Advanced Installer_rgbhi的博客-程序员资料

工欲善其事必先利其器打包我们使用Advanced Installer工具贴个下载链接,笔者亲测,可以使用Advanced Installer 18中文破解版下载 v18.0(附破解补丁+破解教程) - zd4231、安装好之后像这样2、新建一个项目3、填写配置随便填吧,想叫啥叫啥这里我选择用msi包作为输出,可以选择最终的产物的格式,比如exe包什么的填写项目地址,以及输出产物的地址,如果没有文件夹的话,会自动生成的选择VSTO选..._1671465600

单播地址,组播地址,广播地址的区别_coding1994的博客-程序员资料_单播地址,组播地址,广播地址的区别

单播、多播和广播单播”(Unicast)、“多播”(Multicast)和“广播”(Broadcast)这三个术语都是用来描述网络节点之间通讯方式的术语。那么这些术语究竟是什么意思?区别何在?1.单播:网络节点之间的通信就好像是人们之间的对话一样。如果一个人对另外一个人说话,那么用网络技术的术语来描述就是“单播”,此时信息的接收和传递只在两个节点之间进行。单播在网络中得到了广泛的应用,网络

随便推点

思科路由器:RIP动态路由协议实验_spokes的博客-程序员资料_cisco rip实验

1、RIP简介RIP(Routing Information protocol) 路由信息协议.是一种内部网关协议(IGP),是一种动态路由选择协议,用于自治系统(AS)内的路由信息的传递。RIP协议基于距离矢量算法(DistanceVectorAlgorithms),使用“跳数”(即metric)来衡量到达目标地址的路由距离。RIP通过UDP报文进行路由信息交换,使用的端口号为520.RIP包括RIP-v1和RIP-v2两个版本2、RIPV1和RIPV2比较RIPV1RIPV2

英文单词Advanced的意思_宋哥的博客-程序员资料_advance到底表示前期还是后期

iamlaosong文仓储系统WMS中有个ASN的概念,ASN的英文是Advanced Shipping Notice,直译就是提前装运通知,又叫预期收货通知。预期收货通知通常被用于仓库中的实际收货,能减少数据输入时间和简化收货流程。Advanced的意思印象中就是高级的、先进的,这儿的意思是提前的,查阅Advanced的翻译,发现还有晚期的和后期的意思,很不理解,这不是和提前的意思相反吗?怎...

【数论-Lucas定理】_MatrixYg的博客-程序员资料_lucas定理

1.写在前面:我始终觉得,对于一个问题要知其然,更要知其所以然。Lucas定理在刚刚接触数论的时候就知道了,因为这是一个很常用的定理,常常和中国剩余定理放在一起考。最近在组合数学上出现了很多问题,但是都是找个结论就过去了。浑浑噩噩并不懂其中原理,感觉自己的数学直觉一直在下降,以前我甚至能够从数据中看出来数学表达式,后来学了很多的工具,就变懒了,甚至连一个稍微复杂一点的积分都懒得动手,直接自适应Si...

C语言 基础的数学思维题_大师匈的博客-程序员资料

大师匈觉得C语言博大精深,一个合格的程序员不仅要有严密的逻辑思维,精通MCU啊,操作系统啊,各种行业相关的听起来很高大上的东西,而且要有数学思维,敏锐的嗅觉出色的debug能力,混迹几年,发现一些很基础的数学思维竟然也开始僵化了;如不等式,如排列组合的各种灵活应用,可能平时用的少,但是有一些空闲,多练习一些,让自己多思考一下,不至于让自己的脑子逐渐僵化。第一题:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?先不用程序实现,直接去算,有多少种,如果你还记得高中的排列组合,那么

docker overlay2占用大量磁盘空间清理_背儿头的博客-程序员资料_linux docker overlay2 删除无用的

docker overlay2占用大量磁盘空间清理环境前因正文欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片环境docker版本:Docker version 1.13.1, build 7f2769b/1.13.1linux版本Linux version 3.10.0-693.2.2.el7.x86_64前因线上系统出现问题,磁盘空间不足,导致线上系统不可用,最终定位到了问题原因,这篇文章就是记录清理overlay2目_1671465600

CPU频率与内存频率的关系_goldenvenus的博客-程序员资料

首先搞清晰内存的三个频率,核心频率,工作频率,等效频率(也成接口频率),平时常说的DDR2 800中的那个800就是该内存的等效频率(接口频率),也是最有意义的频率,和内存总线的带宽直接挂钩,比如说DDR2 800的带宽算法就是800mhz×64/8也就是6.4GB/S。而工作频

推荐文章

热门文章

相关标签