代理模式

概念:

  1. 真实对象:被代理的对象
  2. 代理对象
  3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的

实现方式:

静态代理

有一个类文件描述代理模式

动态代理

在内存中形成代理类

实现步骤:

  1. 代理对象和真实对象实现相同的接口
  2. 代理对象 = Proxy.newProxyInstance();
  3. 使用代理对象调用方法。
  4. 增强方法

示例:

  1. 创建代理接口SaleComputer

    1
    2
    3
    4
    5
    package com.uestc.proxy;
    public interface SaleComputer {
    public String sale(double money);
    public void show();
    }
  2. 创建真实类Lenovo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.uestc.proxy;
    /**
    * 真实类
    */
    public class Lenovo implements SaleComputer {
    @Override
    public String sale(double money) {
    System.out.println("花了"+money+"买了一台联想电脑");
    return "联想电脑";
    }
    @Override
    public void show() {
    System.out.println("展示电脑。。");
    }
    }
  3. 创建代理测试类ProxyTest

    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
    package com.uestc.proxy;


    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    public class ProxyTest {
    public static void main(String[] args) {
    //1.创建真实对象
    Lenovo lenovo=new Lenovo();

    //2.动态代理增强lenovo对象
    /**
    * 三个参数:
    * 1.类加载器:真实对象.getClass().getClassLoader()
    * 2. 接口数组:真实对象.getClass().getInterfaces()
    * 3. 处理器:new InvocationHandler()
    */

    SaleComputer proxy_lenono=(SaleComputer)Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
    /**
    * 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
    * @param proxy 代理对象
    * @param method 代理对象调用的方法,被封装为对象
    * @param args 代理对象调用的方法传递的实际参数
    * @return
    * @throws Throwable
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println(method.getName());
    System.out.println(args[0]);
    return null;
    }
    });
    //2.调用方法
    String compute=proxy_lenono.sale(8000);
    System.out.println(compute);
    }
    }

    效果展示:

问题:这里代理对象并没有执行真实对象的sale方法,那么我们怎么执行呢?

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
package com.uestc.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo=new Lenovo();

//2.动态代理增强lenovo对象
/**
* 三个参数:
* 1.类加载器:真实对象.getClass().getClassLoader()
* 2. 接口数组:真实对象.getClass().getInterfaces()
* 3. 处理器:new InvocationHandler()
*/
SaleComputer proxy_lenono=(SaleComputer)Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
/**
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* @param proxy 代理对象
* @param method 代理对象调用的方法,被封装为对象
* @param args 代理对象调用的方法传递的实际参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这里相当于使用真实对象调用该方法
Object oj=method.invoke(lenovo,args);
return oj;
}
});
//2.调用方法
String compute=proxy_lenono.sale(8000);
System.out.println(compute);
}
}

增强方式:

  1. 增强参数列表
  2. 增强返回值类型
  3. 增强方法体执行逻辑
1. 增强参数列表

代理商折扣money

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
package com.uestc.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo=new Lenovo();
//2.动态代理增强lenovo对象
/**
* 三个参数:
* 1.类加载器:真实对象.getClass().getClassLoader()
* 2. 接口数组:真实对象.getClass().getInterfaces()
* 3. 处理器:new InvocationHandler()
*/
SaleComputer proxy_lenono=(SaleComputer)Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
/**
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* @param proxy 代理对象
* @param method 代理对象调用的方法,被封装为对象
* @param args 代理对象调用的方法传递的实际参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是否是sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money=(double)args[0];
money=money*0.85;
Object oj=method.invoke(lenovo,money);
return oj;

}else{
Object oj=method.invoke(lenovo,args);
return oj;
}
}
});
//2.调用方法
String compute=proxy_lenono.sale(8000);
System.out.println(compute);
}
}

2. 增强返回值类型

代理商返回给用户电脑加额外的鼠标垫

3. 增强方法体执行逻辑
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
package com.uestc.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo=new Lenovo();
//2.动态代理增强lenovo对象
/**
* 三个参数:
* 1.类加载器:真实对象.getClass().getClassLoader()
* 2. 接口数组:真实对象.getClass().getInterfaces()
* 3. 处理器:new InvocationHandler()
*/

SaleComputer proxy_lenono=(SaleComputer)Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
/**
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* @param proxy 代理对象
* @param method 代理对象调用的方法,被封装为对象
* @param args 代理对象调用的方法传递的实际参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是否是sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money=(double)args[0];
money=money*0.85;
System.out.println("专车接你。。。");
Object oj=method.invoke(lenovo,money);
System.out.println("免费送货。。。");
return oj+"_鼠标垫";

}else{
Object oj=method.invoke(lenovo,args);
return oj;
}
}
});
//2.调用方法
String compute=proxy_lenono.sale(8000);
System.out.println(compute);
}
}