Spring AOP铺垫-----动态代理模式_百步穿杨张巍警的博客-程序员秘密

技术标签: spring  

spring aop的底层原理就是动态代理模式:
代理模式分成两种:1.静态代理模式2.动态代理模式
所谓静态代理就是在运行程序前,程序员手动创建好了代理类,之后运行程序。而动态代理类是通过反射机制,在运行程序的时候,由Java的虚拟机创建出一个代理类。无需程序员手动敲代码,减少了工作的复杂性。

动态代理模式

举例:
动物都有会叫的方法,这时一只猫会叫,这是我需要调猫的shout(叫)的方法。代码如下:

//接口
public interface Animal {
    public void shout();
}
//猫实现动物会叫的接口,并重写shout方法
public class Cat implements Animal{

    @Override
    public void shout() {
        System.out.println("我是一只猫,我正在叫~~~miao");
    }
}
//junit注解,运行程序,创建一只猫,让它叫····
public class TestShout {
    @Test
    public void test1(){
        Animal animal=new Cat();
        animal.shout();
    }
}

在这里插入图片描述
结果轻松愉快的叫了一声 miao~~~现在同样的例子,我们可以通过实现动物接口,重写方法让狗叫,鸡叫,都可以。这也是比较简单的事情。现在,需求上升,需要每个动物叫之前自报家门,叫之后告诉我们叫完了。如何实现:
1.直接在接口的实现类中增加方法

public class Cat implements Animal{

    @Override
    public void shout() {
        before();
        System.out.println("我是一只猫,我正在叫~~~miao");
        after();
    }
    //创建两个方法,添加到shout方法
    
    public void before(){
        System.out.println("我叫张天爸,来自西域!");
    }
    public void after(){
        System.out.println("叫完了,你可以睡觉了!");
    }
}

在这里插入图片描述好像解决了~~~
但这是会有一个问题,如果动物园每只都要以这种方式叫上一遍,岂不是要累死程序员,就算将方法抽出,也需要在实现类中调方法(怪不得程序员头发这么少)。
这时就介绍我们今天的主角,通过动态代理模式来实现:
同样是猫叫的方法,创建动态代理类,Proxy

public class ProxyAnimal implements InvocationHandler {  
    //创建猫的对象
    private Animal animal;
    
   //必须要写带参构造方法
    public ProxyAnimal(Animal animal) {
        this.animal=animal;
    }
    
//在实现InvocationHandler类的时候需要重写invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //shout方法执行前要做的事
        System.out.println("我来自黄土高坡");
        method.invoke(animal,args);
        //shout方法之后要做的事
        System.out.println("不吹牛逼啦,我要睡觉");
        return null;
    }
}

好像也不是很难理解,method.invoke是执行被代理的对象的方法,如果有返回值,可以通过return传递,Object[] args,是被代理对象中的参数集合,至于Object proxy是一个很重要的东西,不要随便改就对啦。(我吧,我承认我不了解,回头弄明白之后一定补上。。。。)
剩下的就是调方法执行程序

public class TestProxyShout {

    Animal animal=new Cat();

    @Test
    public void test1(){
        Animal cat = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), 
                                                     animal.getClass().getInterfaces(), 
                                                     new ProxyAnimal(animal));
        cat.shout();
    }
}

/*
*
* Proxy.newProxyInstance();
* 第一个参数被代理类的classloader
* 第二个参数是被代理类的所有接口
* 第三个参数是处理类
*
* */

在这里插入图片描述

动态代理模式完成!
动态代理模式的优点在于,不改变原有的代码实现代理功能。(工作中去改别人的代码是一件很讨厌的事情),代理逻辑与业务逻辑是互相独立的,没有耦合,代理1个类100个类没有任何区别。但是写起来还是有点繁琐,所以,Spring框架帮我们完成了这件事情,传说中的AOP面向切面编程思想。底层就是动态代理。

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

智能推荐

msgbox的各种按钮_msgbox按钮类型-程序员秘密

以上消息框的用法是在CWnd的子类中的应用,如果不是,则要MessageBox(NULL,"ddd","ddd",MB_OK);MessageBox对话框是比较常用的一个信息对话框,其不仅能够定义显示的信息内容、信息提示图标,而且可以定义按钮组合及对话框的标题,是一个功能齐全的信息对话框信息提示图标,而且可以定义按钮组合及对话框的标题,是一个功能齐全的信息对框。","这是标题", MB_ICONEXCLAMATION|MB_OKCANCEL );//一个是按钮,一个否按钮,一个取消按钮。

springboot jedis配置以及集群(第四篇) 实现redis单机和集群_jedispool 集群配置_弘宇的IT屋的博客-程序员秘密

1.引入pom<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version></dependency>2.实现自动配置导入2.1定义yml内容redis: cluster: nodes: 192.168.1.47:80...

Win10安装TensorFlow2.1.0+PyTorch1.3.1纪实_pytorch1.3.1对应的cuda_X-funbean的博客-程序员秘密

放寒假了,又到了折腾新环境的时间。截止目前(2020年1月15日),TensorFlow的最新版本为2.1.0,PyTorch的最新版本为1.3.1。作为强迫症,也为可能的工程化考虑,希望能够把它们安装在同一个环境中。基本环境:windows10Python3.6首先在Anaconda中新建一个名叫cv的Conda环境:conda create -n cv python=3.6...

就如何解决from lxml import etree报红的问题_from lxml import etree飘红_小阔爱_data的博客-程序员秘密

这个主要是针对在Windows上运行pycharm,lxml和etree下面都报红的问题,自己解决了二个小时研究出来的。原因:主要是lxml没有这个包的问题,需要安装下: 1.需要在https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 下选择你和你对应的pycharm对应的版本下载,下载到桌面上 2.在黑屏终端打开,pip install +

OpenCV-Python官方示例文档_opencv-python官方文档_骚火棍的博客-程序员秘密

链接:https://docs.opencv.org/4.0.1/d6/d00/tutorial_py_root.html

Locust 安装教程_菜狗瑞的博客-程序员秘密

Locust 安装1、安装依赖包1、gevent 微线程库(Coroutine)2、flask 轻量级Web 开发框架。3、Requests 用来做 HTTP 接口测试。4、msgpack-python 二进制序列化格式,适用于类似JSON的数据。2、安装locustpip install locust...

随便推点

Console 执行 ls 中文显示乱码的解决方法_ls 中文乱码_wenenshaoke的博客-程序员秘密

在 Windows下实现 Linux 编程经常需要用到 ls,gcc,df,ps,kill 等命令然而 ls 命令在 cmd 下显示中文出现乱码,在 cygwin/MinGW 中通过修改参数可以使其支持中文显示可以有个简单的方法,即使用 doskey 命令创建宏写法:doskey ls=ls --show-control-chars --color (但是这样的操作在每次进

解决 INTERNAL_SERVER_ERROR java.lang.NullPointerException: null_[error 2023-05-21 10:51:19,715 api.py:75] internal_人生匆匆的博客-程序员秘密

出现以下报错空指针错误,应该是你的servlet里面某个地方接值的时候没接到,然后下面引用了这个值可以查看数据库是否有数据我发现没有数据,可能是我没初始化好,没添加数据再次初始化查看日志无报错了...

Axure元件-母版的应用_Bruce小鬼的博客-程序员秘密

Axure元件-母版的应用1.母版使用场景概述设计网站页面中相同的信息可以使用母版,它的实际功能相当于模板。每个页面相同的元素需要修改时,只需要修改母版内容,其他引用母版的页面元素都会相应改变。省去了每个页面都要重复操作。2.添加母版选中需要转为母版的素材在素材上右键选择转为母版母版上双击修改母版信息-双击母版后自动跳转到模板名称页面–修改信息查看其它元素信息同样被修改...

Python groupby 分组 再求平均值 求和 agg聚合 transform不改变形状应用函数_python groupby transform_正在学习中的李斌的博客-程序员秘密

一、 groupby 依据某列分组; groupby 依据多列分组; 二、应用 mean sum count std median size max min等函数聚合数据; 三、transform 不改变数据形状(相当于计算后替换原来的每一个元素)

从前端转到后台_z610820196的博客-程序员秘密

我目前是做前端的,但是觉得做前端没什么前途,工资也比搞后台的低,最近一直在自学J2EE,大家说从前端转后台容易吗,有没有什么好的学习方法或者建议啊...

线程停止:Thread正确关闭线程的方式_thread 关闭线程_jushisi的博客-程序员秘密

参考:https://artisan.blog.csdn.net/article/details/101174377https://blog.csdn.net/jiadajing267/article/details/80137006文章目录一、使用停止标记(volatile变量)二、发起中断、响应中断 (interrupt)三、生产者、消费者要停止线程,得保证任务处理完四、一、使用停止标记(volatile变量)public class StopThread_1 { public .

推荐文章

热门文章

相关标签