代理模式(2):动态代理

一,动态代理介绍

  • 动态代理和静态代理的角色都是一样,静态代理模式的代理类是我们提前写好的,而动态代理的类是动态生成的,其实动态代理与静态代理的本质一样,最终程序运行时都需要生成一个代理对象实例,通过它来完成相关增强以及业务逻辑,只不过静态代理需要硬编码的方式指定,而动态代理支持运行时动态生成这种实现方式。动态生成的好处很明显,在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合

 

二,与动态代理相关的两个类

  •  Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现
  • Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
    Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
    Static Class getProxyClass (ClassLoader loader,Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组

 

三,代码实现动态代理

1,抽象角色

复制代码
1 //抽象角色
2 public interface User {
3 
4     public void add();
5 
6 }
复制代码

 

2,真实角色

复制代码
1 //真实角色
2 public class UserImpl implements User {
3 
4     public void add() {
5         System.out.println("这是一个add方法");
6     }
7 
8 }
复制代码

 

3,动态代理类生成的接口对象

复制代码
 1 import java.lang.reflect.InvocationHandler;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Proxy;
 4 
 5 public class InvocationHandlerProxy  implements InvocationHandler {
 6 
 7     private User user;
 8 
 9     public void setUser(User user) {
10         this.user = user;
11     }
12 
13     //动态生成代理类
14     public Object getProxy(){
15         return Proxy.newProxyInstance(this.getClass().getClassLoader(),
16                 user.getClass().getInterfaces(),this);
17     }
18 
19     //proxy:代理类
20     //method:代理类的调用处理程序的方法 的对象
21     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
22         show1();
23         Object invoke = method.invoke(user, args);
24         show2();
25         return invoke;
26     }
27 
28     public void show1(){
29         System.out.println("show方法1");
30     }
31 
32     public void show2(){
33         System.out.println("show方法2");
34     }
35 }
复制代码

【注意InvocationHandler导包】

 

 4,测试

复制代码
 1 public class Test {
 2     public static void main(String[] args) {
 3 
 4         UserImpl userImpl = new UserImpl();
 5 
 6         InvocationHandlerProxy ihp = new InvocationHandlerProxy();
 7         ihp.setUser(userImpl);
 8 
 9         User proxy = (User) ihp.getProxy();
10 
11         proxy.add();
12     }
13 }
复制代码

 

5,运行结果

 

 

四,总结

 动态代理的好处

  • 可以使真实角色更加纯粹,不用去关注一些公共的事情
  • 公共的业务由代理来完成,实现业务的分工
  • 公共业务的要扩展的话,可以更加集中和方便
  • 一个动态代理,一般代理一类的业务,一个动态代理可以代理多个类,代理接口
posted @ 2020-07-20 10:51  edda_huang  阅读(124)  评论(0编辑  收藏  举报