设为首页 加入收藏

TOP

设计模式---代理模式(二)
2019-09-02 23:52:43 】 浏览:47
Tags:设计模式 --- 代理 模式
t;买房后装修"); 24 return result; 25 } 26 }

第二步:编写测试类

 1 package main.java.proxy.test;
 2 
 3 import main.java.proxy.BuyHouse;
 4 import main.java.proxy.impl.BuyHouseImpl;
 5 import main.java.proxy.impl.DynamicProxyHandler;
 6 
 7 import java.lang.reflect.Proxy;
 8 
 9 /**
10  * @Auther: dan gao
11  * @Description:
12  * @Date: 20:38 2018/1/12 0012
13  */
14 public class DynamicProxyTest {
15     public static void main(String[] args) {
16         BuyHouse buyHouse = new BuyHouseImpl();
17         BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
18                 Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
19         proxyBuyHouse.buyHosue();
20     }
21 }

 注意Proxy.newProxyInstance()法接受三个参数:

  • ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
  • Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法

动态代理总结:虽然相对于静态代理,动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对 class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例

3.CGLIB代理

       JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

第一步:创建CGLIB代理类

 1 package dan.proxy.impl;
 2 
 3 import net.sf.cglib.proxy.Enhancer;
 4 import net.sf.cglib.proxy.MethodInterceptor;
 5 import net.sf.cglib.proxy.MethodProxy;
 6 
 7 import java.lang.reflect.Method;
 8 
 9 /**
10  * @Auther: dan gao
11  * @Description:
12  * @Date: 20:38 2018/1/16 0016
13  */
14 public class CglibProxy implements MethodInterceptor {
15     private Object target;
16     public Object getInstance(final Object target) {
17         this.target = target;
18         Enhancer enhancer = new Enhancer();
19         enhancer.setSuperclass(this.target.getClass());
20         enhancer.setCallback(this);
21         return enhancer.create();
22     }
23 
24     public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
25         System.out.println("买房前准备");
26         Object result = methodProxy.invoke(object, args);
27         System.out.println("买房后装修");
28         return result;
29     }
30 }

 

第二步:创建测试类

 1 package dan.proxy.test;
 2 
 3 import dan.proxy.BuyHouse;
 4 import dan.proxy.impl.BuyHouseImpl;
 5 import dan.proxy.impl.CglibProxy;
 6 
 7 /**
 8  * @Auther: dan gao
 9  * @Description:
10  * @Date: 20:52 2018/1/16 0016
11  */
12 public class CglibProxyTest {
13     public static void main(String[] args){
14         BuyHouse buyHouse = new BuyHouseImpl();
15         CglibProxy cglibProxy = new CglibProxy();
16         BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);
17         buyHouseCglibProxy.buyHosue();
18     }
19 }

 

CGLIB代理总结: CGLIB创建的动态代理对象比JDK创建的动态代理对象的性能更高,但是CGLIB创建代理对象时所花费的时间却比JDK多得多。所以对于单例的对象,因为无需频繁创建对象,用CGLIB合适,反之使用JDK方式要更为合适一些。同时由于CG

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇JDBC、mybatis、hibernate连接数.. 下一篇设计模式复习小结一(Strategy Pat..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目