• Spring框架——了解AOP和动态代理


    老规矩上图

    请添加图片描述

    Spring核心AOP:面向切面编程,可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率,说的就是什么都不动,通过AOP可以增强原先设计的程序

    案例展示:写一个程序来判断名字是不是你的同学
    在这里插入图片描述
    这是在正常情况下实现程序的流程,但是有一个疑问假设你的同学名字叫小明是一个男性,而我们输入同学的姓名可能是一个女性,这是我们就必须修改原本的程序,但是只要修改代码就可能出现各种各样的问题,而AOP就可以解决这种问题,在代码不动的情况下加一个判断,来确保程序稳定的执行下去。

    **

    AOP的底层原理

    **

    动态定理:利用jdk的反射机制,执行创建对象的能力,创建的是代理类的对象 在内部使用的是动态代理两种:

    1. 有接口的,jdk动态代理(创建接口实现类的代理对象)
    2. 没有接口的,CGLIB动态代理(创建当前子类的代理对象)

    代码实现
    1.创建接口,定义其中的方法

    interface aa{       
        public int lj(int a,int b);
        public String play(String c);
    
    
    • 1
    • 2
    • 3
    • 4

    2.创建接口实现类,实现接口中定义的方法

    class JDKdemo1 implements aa{
        @Override
        public int lj(int a, int b) {
            System.out.println("ljljljjljl");
            return a+b;
        }
    
        @Override
        public String play(String c) {
            System.out.println("playplayplayplayplayplay");
            return c;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.创建代理对象

    class jdkdemo1proxy implements InvocationHandler{  //创建的代理对象类继承
    	//.InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。
        private Object obj;           //创建通用对象,可以导入各个类
        public jdkdemo1proxy(Object obj){  
            this.obj=obj;
        }
    	//添加需要添加的功能,增强完善原本的程序
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        	//在执行原本方法之前进行输出
            System.out.println("最开始执行"+method.getName()+"传入的参数"+ Arrays.toString(args));
            //原本的功能进行输出
            Object res= method.invoke(obj, args);
            
            System.out.println("什么都执行完了");
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    4.将创建的接口代理对象

    调用 newProxyInstance 方法 方法有三个参数: 第一参数,类加载器
    第二参数,增强方法所在的类,这个类实现的接口,支持多个接口 第三参数,实现这个接口
    InvocationHandler,创建代理对象,写增强的部分

    class jdkproxy{
        public static void main(String[] args) {
    
    
            Class[] inter1 = {aa.class};
            JDKdemo1 JD = new JDKdemo1();
            aa aa =(aa)Proxy.newProxyInstance(jdkproxy.class.getClassLoader(),inter1,new jdkdemo1proxy(JD));
            int bb= aa.lj(1,2);
            String cc= aa.play("3");
            System.out.println(bb);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.输出结果

    最开始执行lj传入的参数[1, 2]
    ljljljjljl
    什么都执行完了
    最开始执行play传入的参数[3]
    playplayplayplayplayplay
    什么都执行完了
    3


    动态代理:jdk动态代理完整代码


    package new_study.AOP;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Arrays;
    
    public class JDKdemo1 implements aa{
        @Override
        public int lj(int a, int b) {
            System.out.println("ljljljjljl");
            return a+b;
        }
    
        @Override
        public String play(String c) {
            System.out.println("playplayplayplayplayplay");
            return c;
        }
    }
    
    interface aa{
        public int lj(int a,int b);
        public String play(String c);
    
    }
    class jdkproxy{
        public static void main(String[] args) {
    
    
            Class[] inter1 = {aa.class};
            JDKdemo1 JD = new JDKdemo1();
            aa aa =(aa)Proxy.newProxyInstance(jdkproxy.class.getClassLoader(),inter1,new jdkdemo1proxy(JD));
            int bb= aa.lj(1,2);
            String cc= aa.play("3");
            System.out.println(bb);
    
        }
    }
    class jdkdemo1proxy implements InvocationHandler{
        private Object obj;
        public jdkdemo1proxy(Object obj){
            this.obj=obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("最开始执行"+method.getName()+"传入的参数"+ Arrays.toString(args));
            Object res= method.invoke(obj, args); //调用并执行原本的功能方法
            System.out.println("什么都执行完了");
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
  • 相关阅读:
    二叉树的建立与遍历
    Python爬虫-贝壳新房
    【算法|动态规划No.26】leetcode1745. 分割回文串 IV
    [游戏开发][Untiy]跨平台可视化Log系统
    java-net-php-python-45ssm校园小商品二手交易系统计算机毕业设计程序
    『外卖好评(通用50字)』
    4.2——Node.js的npm和包
    Vue.prototype详解
    【NLP】使用 NLTK 解析与生成上下文无关文法(Context-free Grammar)
    MySQL基础进阶:汇总数据
  • 原文地址:https://blog.csdn.net/m0_52479012/article/details/127128401