码迷,mamicode.com
首页 > 其他好文 > 详细

动态代理

时间:2017-12-14 04:06:06      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:his   lang   类加载器   port   object   运行时   factory   src   images   

1、动态代理

在运行时,动态创建一组指定的接口的实现类对象!(在运行时,创建实现了指定的一组接口的对象)

interface A {}
interface B {}

Object o = 方法(new Class[]{A.class,B.class})
o它实现了A和B两个接口!
-------------
Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h);
1. 方法作用:动态创建实现了interfaces数组中所有指定接口的实现类对象!
参数;
1. ClassLoader:类加载器!
* 它是用来加载器的,把.class文件加载到内存,形成Class对象!

技术分享图片

2. Class[] interfaces:指定要实现的接口们
3. InvocationHandler:代理对象的所有方法(个别不执行,getClass())都会调用InvocationHandler的invoke()方法。
---------------------------------------------------------
2. 动态代理作用
最终是学习AOP(面向切面编程),它与装饰者模式有点相似,它比装饰者模式还要灵活!
----------------------------------------------------------

InvocationHandler

public Object invoke(Object proxy, Method method, Object[] args);

这个invoke()方法在什么时候被调用!在调用代理对象所实现接口中的方法时

技术分享图片

  • Object proxy:当前对象,即代理对象!在调用谁的方法!
  • Method method:当前被调用的方法(目标方法)
  • Object[] args:实参!
----------------------------

目标对象:被增强的对象
代理对象:需要目标对象,然后在目标对象上添加了增强后的对象!
目标方法:增强的内容

代理对象 = 目标对象 + 增强

技术分享图片

 

Waiter案例1:
 1 package demo2;
 2 
 3 import org.junit.Test;
 4 import java.lang.reflect.InvocationHandler;
 5 import java.lang.reflect.Method;
 6 import java.lang.reflect.Proxy;
 7 
 8 public class Demo2 {
 9     @Test
10     public void fun1() {
11         Waiter manWaiter = new ManWaiter();
12         /*
13         * 给出三个参数,来创建方法,得到代理对象
14         * */
15         ClassLoader loader = this.getClass().getClassLoader();
16         Class[] interfaces = {Waiter.class};
17         InvocationHandler h = new WaiterInvocationHandler(manWaiter);//参数manWaiter类表示目标对象
18         //得到代理对象,代理对象就是在目标对象的基础上进行了增强的对象!
19         Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(loader,interfaces,h);
20         waiterProxy.serve();//前面添加"你好",后面添加"再见"
21 
22     }
23 }
24 class WaiterInvocationHandler implements InvocationHandler {
25     private Waiter waiter;//目标对象
26 
27     public WaiterInvocationHandler(Waiter waiter) {
28         this.waiter = waiter;
29     }
30     @Override
31     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
32         System.out.println("您好!");
33         this.waiter.serve();//调用目标对象的目标方法
34         System.out.println("再见!");
35         return null;
36     }
37 }
1 package demo2;
2 
3 public class ManWaiter implements Waiter {
4     @Override
5     public void serve() {
6         System.out.println("服务中...");
7     }
8 }
1 package demo2;
2 
3 //服务
4 public interface Waiter {
5     //服务
6     public void serve();
7 }

 案例2:

 1 /**
 2  * 目标是让目标对象和增强都可以切换!
 3  */
 4 public class Demo3 {
 5     @Test
 6     public void fun1() {
 7         ProxyFactory factory = new ProxyFactory();
 8         factory.setTargetObject(new ManWaiter());
 9         factory.setBeforeAdvice(new BeforeAdvice() { //设置前置增强
10             @Override
11             public void before() {
12                 System.out.println("您好!");
13             }
14         });
15         factory.setAfterAdvice(new AfterAdvice() { //设置后置增强
16             @Override
17             public void after() {
18                 System.out.println("再见!");
19             }
20         });
21 
22         Waiter waiter = (Waiter) factory.createProxy();
23         waiter.serve();
24     }
25 }
 1 package demo3;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 /**
 8  * 它用来生成代理对象
 9  * 它需要所有的参数
10  *    目标对象
11  *    增强
12  */
13 /*
14 * 1、创建代理工厂
15 * 2、给工厂设置三样东西:
16 *   目标对象:setTargetObject(XXX);
17 *   前置增强:setBeforeAdvice(该接口的实现)
18 *   后置增强:setAfterAdvice(该接口的实现)
19 * 3、调用createProxy()得到代理对象
20 *   执行代理对象方法时:
21 *       执行BeforeAdvice的before()
22 *       目标对象的目标方法
23 *       执行AfterAdvice的after()
24 * */
25 public class ProxyFactory {
26     private Object targetObject;//目标对象
27     private BeforeAdvice beforeAdvice;//前置增强
28     private AfterAdvice afterAdvice;//后置增强
29 
30     //用来生成代理对象
31     public Object createProxy() {
32         /*
33         * 1、给出三大参数
34         * */
35         ClassLoader loader = this.getClass().getClassLoader();
36         Class[] interfaces = targetObject.getClass().getInterfaces();
37         InvocationHandler h = new InvocationHandler() {
38             @Override
39             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
40                 /*
41                 * 在调用代理对象的方法时会执行这里的内容
42                 * */
43                 //执行前置增强
44                 if (beforeAdvice != null) {
45                     beforeAdvice.before();
46                 }
47                 Object result = method.invoke(targetObject,args);//执行目标对象的目标方法
48                 //执行后置增强
49                 if (afterAdvice != null) {
50                     afterAdvice.after();
51                 }
52                 return result;
53             }
54         };
55         //2、得到代理对象
56         Object proxObject = Proxy.newProxyInstance(loader,interfaces,h);
57         return proxObject;
58     }
59     public Object getTargetObject() {
60         return targetObject;
61     }
62     public void setTargetObject(Object targetObject) {
63         this.targetObject = targetObject;
64     }
65     public BeforeAdvice getBeforeAdvice() {
66         return beforeAdvice;
67     }
68     public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
69         this.beforeAdvice = beforeAdvice;
70     }
71     public AfterAdvice getAfterAdvice() {
72         return afterAdvice;
73     }
74     public void setAfterAdvice(AfterAdvice afterAdvice) {
75         this.afterAdvice = afterAdvice;
76     }
77 }
1 /**
2  * 前置增强
3  */
4 public interface BeforeAdvice {
5     public void before();
6 }
1 /**
2  * 后置增强
3  */
4 public interface AfterAdvice {
5     public void after();
6 }

 

动态代理

标签:his   lang   类加载器   port   object   运行时   factory   src   images   

原文地址:http://www.cnblogs.com/gdwkong/p/8035120.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!