A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 大梅 黑马帝   /  2012-1-26 11:22  /  3022 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 大梅 于 2012-1-27 18:18 编辑

第一次看视频的时候一直疑惑Proxy怎么能实现对了class的代理呢?后来看了篇文章,说由于Java不能支持多继承,故无法实现对class的代理。
对动态代理还是雾里看花,似懂非懂。
哪位仁兄给俺出个练习做做?

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

8 个回复

倒序浏览
  代理分静态代理和动态代理,先弄清楚简单些的静态代理。
  比如,你已写了多个计算面积的类,现要求在输出前增加标识:“黑马程序员第6届”,你当然可以去修改输出语句,或在前面增加一输出语句,但如果变成“黑马程序员第7届”呢,又要逐个修改,一般的方法是:写一个类,里面有输出标识的方法;用时调用这个类的方法。
  静态代理将上面含有输出标识的方法的类,分成三个类:接口类、接口的实现类 、静态代理类。有什么好处先不管,看看例子:(可以先写写,再看代码)
1.接口类
  1. public interface TestProxy {      
  2.     public void print();      
  3. }
复制代码
2.接口的实现类
  1. public class TestProxyImpl implements TestProxy{      
  2.       
  3.     public void print(){      
  4.         System.out.println("黑马程序员");      
  5.     }
  6. }
复制代码
3.静态代理类
  1. public class StaticProxy implements TestProxy{      
  2.       
  3.     public TestProxy testProxy ;      
  4.     public StaticProxy(TestProxy testProxy){      
  5.         this.testProxy = testProxy;      
  6.     }      
  7.            
  8.     public void print(){      
  9.         testProxy.print();   //   
  10.         System.out.println("第6届");      
  11.     }
  12. }
复制代码
4.测试
  1. public class TestStaticProxy {
  2.     public static void main(String[] args){      
  3.         TestProxy testProxy = new TestProxyImpl();      
  4.         StaticProxy staticProxy = new StaticProxy(testProxy);      
  5.         staticProxy.print();      
  6.     }      
  7. }
复制代码
动态代理且看下回分解.

评分

参与人数 1技术分 +2 收起 理由
吴上储 + 2

查看全部评分

回复 使用道具 举报
黄秋 发表于 2012-1-27 02:23
  代理分静态代理和动态代理,先弄清楚简单些的静态代理。
  比如,你已写了多个计算面积的类,现要求 ...

谢谢,动态代理就留给我解吧~
回复 使用道具 举报
黄秋 发表于 2012-1-27 02:23
  代理分静态代理和动态代理,先弄清楚简单些的静态代理。
  比如,你已写了多个计算面积的类,现要求 ...

按你的意思,重新编题。有个接口提供几何图形的一些操作,其中有一方法是求面积。写一个为这个接口提供服务的代理类。其中有一个实现好的几何图形,名为圆的累实现了求面积的方法。有了代理类以后,今后如果出现更多的图形来,都可以交给这个代理去处理了。
被代理的接口:
  1. package staticproxy;

  2. interface GeometryUtils {
  3.         public void Space();
  4. }
复制代码
圆:
  1. package staticproxy;

  2. class Cirlce implements GeometryUtils {
  3.         private int r;
  4.         private double s ;
  5.         private final double PI = 3.14;
  6.         public int getR() {
  7.                 return r;
  8.         }

  9.         public void setR(int r) {
  10.                 this.r = r;
  11.         }

  12.         @Override
  13.         public void Space() {
  14.                 // TODO Auto-generated method stub
  15.                 s = r*r*PI;
  16.                 System.out.println("圆的面积: " + s);
  17.         }

  18. }
复制代码
静态代理类:
  1. package staticproxy;
  2. class Advice{
  3.         public static void before(){
  4.                 System.out.println("代理类服务开始");
  5.         }
  6.         public static void after(){
  7.                 System.out.println("代理类服务完成");
  8.         }
  9. }
  10. class MyStaticProxy implements GeometryUtils {
  11.         private GeometryUtils obj = null;
  12.         public MyStaticProxy(Object obj){
  13.                 super();
  14.                 this.obj = (GeometryUtils)obj;
  15.         }
  16.         @Override
  17.         public void Space() {
  18.                 // TODO Auto-generated method stub
  19.                 Advice.before();
  20.                 obj.Space();
  21.                 Advice.after();
  22.         }
  23. }
复制代码
测试:
  1. package staticproxy;

  2. import org.junit.Test;

  3. public class staticProxyTest {
  4.         @Test
  5.         public void test01(){
  6.                 Cirlce c = new Cirlce();
  7.                 c.setR(2);
  8.                 MyStaticProxy proxy = new MyStaticProxy(c);
  9.                 proxy.Space();
  10.         }
  11. }
复制代码
回复 使用道具 举报
写得好,动态代理我也不是十分了解.感觉反射熟练的话,动态代理则会易明白.动态代理中的代理类是由java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动态生成的。个人体会,当看动态代理困难时,先复习下反射.
回复 使用道具 举报
动态代理来做的话如下:
Circle类和GeometryUtils接口不变。
  1. package staticproxy;
  2. import java.lang.annotation.Target;
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Proxy;

  6. import org.junit.Test;

  7. class Advice{
  8.         public static void before(Object obj){
  9.                 System.out.println("代理类服务开始");
  10.                 if(obj instanceof Circle)((Circle)obj).setR(2);
  11.         }
  12.         public static void after(){
  13.                 System.out.println("代理类服务完成");
  14.         }
  15. }

  16. public class MyDynamicProxyTest {
  17.         @Test
  18.         public void test01(){
  19.                 GeometryUtils proxy = (GeometryUtils) Proxy.newProxyInstance(GeometryUtils.class.getClassLoader(),
  20.                                 new Class[]{GeometryUtils.class},
  21.                                 new InvocationHandler() {
  22.                                         Circle target = new Circle();
  23.                                         @Override
  24.                                         public Object invoke(Object proxy, Method method, Object[] args)
  25.                                                         throws Throwable {
  26.                                                 // TODO Auto-generated method stub
  27.                                                 Object reval = null;
  28.                                                 Advice.before(target);
  29.                                                 reval = method.invoke(target, null);
  30.                                                 Advice.after();
  31.                                                 return reval;
  32.                                         }
  33.                                 });
  34.                 proxy.Space();
  35.         }
  36. }
复制代码
回复 使用道具 举报
大梅 黑马帝 2012-1-27 18:17:19
7#
黄秋 发表于 2012-1-27 12:26
写得好,动态代理我也不是十分了解.感觉反射熟练的话,动态代理则会易明白.动态代理中的代理类是由java.l ...

反射是挺有意思的。动态代理中的方法调用确实是反射实现的,这个也挺有趣。
回复 使用道具 举报
{:soso_e113:}学习了,最近没事,就回头看看大家学习中的问题,感觉还是收获蛮大的。
回复 使用道具 举报
djx900 黑马帝 2012-2-28 02:15:05
9#
太受教了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马