当前位置: 首页 > news >正文

小白一步步实现SSM框架之AOP(自己实现)

系列文章:
技术小白学习SSM框架(Spring、SpringMVC、MyBatis)
小白一步步实现SSM框架之IOC(自己实现)
小白一步步实现SSM框架之MYBATIS( 存储过程)

AOP实现原理:通过学习IOC和AOP,其中最重要的一个框架中需要加入反射的

学习原理

  1. 能更好的掌握Spring的使用。

  2. 能进行对Spring功能更好的扩展及其衍生。

  3. 一个好的框架涉及到的技术和知识全面,可以对基础知识能有更好的巩固和理解。

  4. 学习一个框架也为自己开发框架提供很多借鉴的地方。

一、反射生成JDK动态代理

(一)JDK动态代理原理

Proxy两个方法创建动态代理类和动态代理实例

java 17 查找网站

Overview (Java SE 17 & JDK 17) (oracle.com)

  1. 创建动态代理类

    已经过时了,但是还可以使用

    @Deprecated public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException

参数分别对应动态代理的class对象,代理类实现interfaces多个接口

  1. 动态代理实例

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

    多了一个InvocationHandler接口,这个是接口需要实现的invoke()方法,可以看到来了invoke。

    Object invoke(Object proxy, Method method, Object[] args) throws Throwable

    (二)JDK动态代理代码实现

  2. 创建Person接口

package reflectjdkExample;
public interface Person {void walk();void  sayHello(String name);
}
  1. 创建MyInvocationHandler类

步骤一: 加入InvocationHandler 接口,实现 invoke 方法。

步骤二:以上两种方式的实现,转为Person接口调用两个方法。

package reflectjdkExample;import java.lang.reflect.*;
//import java.util.Arrays;public class MyInvocationHandler implements InvocationHandler {/*** 当执行动态代理对象的所有方法时候,都会被替换成invoke()方法执行* @param proxy 动态代理对象* @param method 执行方法* @param args 传入参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法是什么:"+method);if (args!=null){System.out.println("参数是什么:");// JDK10 引入了var,会自动推断出类型。如果你用的是JDK8 var 替换成 Object ,我用的是JDK17 。for (var val:args){System.out.println(val);}//            Arrays.stream(args).toList().forEach(System.out::println);}else{System.out.println("没有参数");}return null;}public static void main(String[] args) throws NoSuchMethodException,InvocationTargetException, InstantiationException, IllegalAccessException {/**        简化实现版本*         var p=(Person) Proxy.newProxyInstance(*                 Person.class.getClassLoader()*                 ,new Class[]{Person.class},*                 handler);*/// 获取代理类Class proxyClass=Proxy.getProxyClass(Person.class.getClassLoader(),Person.class);// 获取构造方法Constructor ctor=proxyClass.getConstructor(InvocationHandler.class);// 创建代理对象实例var p=(Person) ctor.newInstance(new MyInvocationHandler());p.walk();p.sayHello("sky");}
}

输出结果

方法是什么:public abstract void reflectjdkExample.Person.walk() 没有参数 方法是什么:public abstract void reflectjdkExample.Person.sayHello(java.lang.String) 参数是什么: sky

二、动态代理+AOP

为了解决的问题是把相同的代码抽取出来,只需要修改一处代码即可,提供代码的维护性。

AOP代理的方法实现步骤:

步骤一:动态代理增加的通用方法

步骤二:回调目标对象的方法

步骤三:动态代理增加的通用方法

  1. 加入Person接口的 FlyPerson 类

    package reflectjdkExample;public class FlyPerson implements Person{@Overridepublic void walk() {System.out.println("走的最快");}@Overridepublic void sayHello(String name) {System.out.println("hello," + name);}
    }
  2. 加入PersonUtil 拦截方法类********* 这边就是把通用的方法给抽取出来了,例如每次进行网页跳转的时候进行身份校验。

    package reflectjdkExample;public class PersonUtil {public void method1(){System.out.println("======method1拦截======");}public void method2(){System.out.println("======method2拦截======");}
    }
    
  3. 设置MyProxyFactory代理工厂

    设置代理的目标,1.创建MyInvokationHandler对象,2. 代理目标设置,3.创建并返回动态代理

    package reflectjdkExample;import java.lang.reflect.Proxy;public class MyProxyFactory {public static Object getProxy(Object target)  {var handler = new MyInvokationHandler();handler.setTarget(target);return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);}
    }
    
  4. MyInvokationHandler类

    第一步:实现InvocationHandler 接口的 invoke方法,1创建拦截器,2执行拦截器method1方法,3调用目标对象的方法(具体可以看小白一步步实现SSM框架之IOC(自己实现)文章https://blog.csdn.net/weixin_45631815/article/details/140475054?spm=1001.2014.3001.5501 反射知识点),4执行拦截器method2方法,5 返回调用方法的结果。

    第二步: main 静态方法实现,1创建FlyPerson对象,2 返回动态代理对象并转为Person接口,3.执行接口的sayHello 和 walk方法。

    package reflectjdkExample;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;public class MyInvokationHandler implements InvocationHandler {private Object target;public void setTarget(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {PersonUtil personUtil = new PersonUtil();personUtil.method1();// 调用目标对象的方法Object result = method.invoke(target, args);personUtil.method2();return result;}public static void main(String[] args) {FlyPerson flyPerson = new FlyPerson();Person person = (Person) MyProxyFactory.getProxy(flyPerson);person.sayHello("sky");person.walk();}
    }

    输出

       ======method1拦截======hello,sky======method2拦截============method1拦截======走的最快======method2拦截======
    

三、总结

​ 动态代理+AOP实现,可以解决的是相同的代码抽取。IOC解决了解耦,减少了new 对象。后期会增加IOC和AOP两大功能的结合起来,以及其他的细节功能的增加。

​ 目前准备的是自己手动实现框架形式学习Spring原理,学习好原理之后在应用。

​ 我同时也会遵循(一个好的框架涉及到的技术和知识全面,可以对基础知识能有更好的巩固和理解 )原则。

学习Spring源码资料推荐:
mini-spring

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 直播架构如何设计核心节点和边缘节点
  • ansible安装
  • 人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解
  • 【46 Pandas+Pyecharts | 当当网畅销图书榜单数据分析可视化】
  • 用ssh tunnel的方式设置 AWS DocumentDB 公网访问
  • jvm常用密令、jvm性能优化、jvm性能检测、Java jstat密令使用、Java自带工具、Java jmap使用
  • TensorFlowTTS tts语音合成使用案例;tflite模型转换及加载使用
  • PHP基础语法(一)
  • tomcat的优化
  • verilog bug记录——正点原子spi_drive存在的问题
  • Go语言并发编程-Goroutine调度
  • 51单片机嵌入式开发:12、STC89C52RC 红外解码数码管显示
  • [开源]语雀+Vercel:打造免费个人博客网站
  • 顶顶通呼叫中心中间件-被叫路由、目的地绑定(mod_cti基于FreeSWITCH)
  • Leetcode二分搜索法浅析
  • [笔记] php常见简单功能及函数
  • 2017 年终总结 —— 在路上
  • ES6系统学习----从Apollo Client看解构赋值
  • JAVA多线程机制解析-volatilesynchronized
  • JS笔记四:作用域、变量(函数)提升
  • markdown编辑器简评
  • PHP变量
  • React-flux杂记
  • React-redux的原理以及使用
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 蓝海存储开关机注意事项总结
  • 前端js -- this指向总结。
  • 前端代码风格自动化系列(二)之Commitlint
  • 如何编写一个可升级的智能合约
  • 三分钟教你同步 Visual Studio Code 设置
  • 为视图添加丝滑的水波纹
  • PostgreSQL之连接数修改
  • 阿里云移动端播放器高级功能介绍
  • ​香农与信息论三大定律
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (160)时序收敛--->(10)时序收敛十
  • (java)关于Thread的挂起和恢复
  • (补充)IDEA项目结构
  • (苍穹外卖)day03菜品管理
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)测试工具
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (算法)大数的进制转换
  • (一)基于IDEA的JAVA基础10
  • (已解决)Bootstrap精美弹出框模态框modal,实现js向modal传递数据
  • (转)甲方乙方——赵民谈找工作
  • .NET CLR基本术语
  • .net core docker部署教程和细节问题
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET 通过系统影子账户实现权限维持
  • .net 无限分类
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...