9_Spring_JDK动态代理

曾经终败给现在 2023-09-30 19:57 56阅读 0赞

代理模式

是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。

房产中介代替业主卖房

e7aa4b5d58f48018ffa3de91234092dd.png

静态代理

静态代理中代理类与被代理类都需要实现同一个接口,这就说明我们的一个静态代理类只能代理一个类,并且还要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。然而在实际开发中我们是可能是有非常多的类是需要被代理的,并且事先我们可能并不知道我们要代理哪个类。所以如果继续使用静态代理反而会增加许多的工作量,并且效率低下,代码复用率也不好。

  1. package com.msb.test;
  2. /**
  3. * @Author: Ma HaiYang
  4. * @Description: MircoMessage:Mark_7001
  5. */
  6. public class Test1 {
  7. public static void main(String[] args) {
  8. Person person =new Person("张三");
  9. Court court=new Lawyer(person);
  10. court.doCourt();
  11. }
  12. }
  13. // 接口
  14. interface Court{
  15. void doCourt();
  16. }
  17. // 代理类
  18. class Lawyer implements Court{
  19. private Person person;
  20. public Lawyer(Person person) {
  21. this.person = person;
  22. }
  23. @Override
  24. public void doCourt() {
  25. System.out.println("律师取证:视频证明张三当时正在旅游,不在案发现场");
  26. System.out.println("律师总结:张三不可能去杀人");
  27. person.doCourt();
  28. }
  29. }
  30. // 被代理的类
  31. class Person implements Court{
  32. private String name;
  33. public Person(String name) {
  34. this.name = name;
  35. }
  36. @Override
  37. public void doCourt() {
  38. System.out.println(name+"说:我没有杀人");
  39. }
  40. }

3a1697cbaa15f78b56b6b70d8ec3dfe6.gif

248c186b4c561cfb73abeb6db077cd8e.gif

动态代理

动态代理可以针对于一些不特定的类或者一些不特定的方法进行代理,我们可以在程序运行时动态的变化代理的规则,代理类在程序运行时才创建的代理模式成为动态代理。这种情况下,代理类并不是在Java代码中定义好的,而是在程序运行时根据我们的在Java代码中的“指示”动态生成的

Proxy 动态代理 JDK动态代理 面向接口

cglib 动态代理 第三方动态代理 面向父类

张三吃饭

  1. package com.msb.testProxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import java.util.Arrays;
  6. /**
  7. * @Author: Ma HaiYang
  8. * @Description: MircoMessage:Mark_7001
  9. */
  10. public class Test1 {
  11. public static void main(String[] args) {
  12. Dinner dinner=new Person("张三");
  13. // 通过Porxy动态代理获得一个代理对象,在代理对象中,对某个方法进行增强
  14. // ClassLoader loader,被代理的对象的类加载器
  15. ClassLoader classLoader = dinner.getClass().getClassLoader();
  16. // Class<?>[] interfaces,被代理对象所实现的所有接口
  17. Class[] interaces= dinner.getClass().getInterfaces();
  18. // InvocationHandler h,执行处理器对象,专门用于定义增强的规则
  19. InvocationHandler handler = new InvocationHandler(){
  20. // invoke 当我们让代理对象调用任何方法时,都会触发invoke方法的执行
  21. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  22. // Object proxy, 代理对象
  23. // Method method,被代理的方法
  24. // Object[] args,被代理方法运行时的实参
  25. Object res=null;
  26. if(method.getName().equals("eat")){
  27. System.out.println("饭前洗手");
  28. // 让原有的eat的方法去运行
  29. res =method.invoke(dinner, args);
  30. System.out.println("饭后刷碗");
  31. }else{
  32. // 如果是其他方法,那么正常执行就可以了
  33. res =method.invoke(dinner, args);
  34. }
  35. return res;
  36. }
  37. };
  38. Dinner dinnerProxy =(Dinner) Proxy.newProxyInstance(classLoader,interaces,handler);
  39. //dinnerProxy.eat("包子");
  40. dinnerProxy.drink();
  41. }
  42. }
  43. interface Dinner{
  44. void eat(String foodName);
  45. void drink();
  46. }
  47. class Person implements Dinner{
  48. private String name;
  49. public Person(String name) {
  50. this.name = name;
  51. }
  52. @Override
  53. public void eat(String foodName) {
  54. System.out.println(name+"正在吃"+foodName);
  55. }
  56. @Override
  57. public void drink( ) {
  58. System.out.println(name+"正在喝茶");
  59. }
  60. }
  61. class Student implements Dinner{
  62. private String name;
  63. public Student(String name) {
  64. this.name = name;
  65. }
  66. @Override
  67. public void eat(String foodName) {
  68. System.out.println(name+"正在食堂吃"+foodName);
  69. }
  70. @Override
  71. public void drink( ) {
  72. System.out.println(name+"正在喝可乐");
  73. }
  74. }

5c2031b2b5a8a3a76cf6abf0a4e481cb.gif

cc5c46c414733beff7ef7b85f2c72061.gif

使用代理技术 获得代理对象 代替张三 增强打官司的方法

总结

1在不修改原有代码的 或者没有办法修改原有代码的情况下 增强对象功能 使用代理对象 代替原来的对象去完成功能

进而达到拓展功能的目的

2JDK Proxy 动态代理面向接口的动态代理 一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法

生成的代理对象只能转换成 接口的不能转换成 被代理类

代理对象只能增强接口中定义的方法 实现类中其他和接口无关的方法是无法增强的

代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解

发表评论

表情:
评论列表 (有 0 条评论,56人围观)

还没有评论,来说两句吧...

相关阅读

    相关 9_Spring_JDK动态代理

    代理模式 是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。 房产中介代替业主卖房 ![b9c7284a183c4a6