java动态代理--学习笔记

来源:互联网 发布:哪款男生面膜知乎 编辑:程序博客网 时间:2024/06/01 10:39
最近学习了动态代理,小小的记录了一下
代理是基本的设计模式之一,为你提供额外的操作,用来替代”实际对象(被代理对象)“。通常充当中间人的角色。

动态代理,两个角色: 代理对象 、 被代理对象(委托对象)
以下通过例子来说明(参考《thinking  in java》):

一、声明一个公共接口
Java code
?
1
2
3
4
public interface Interface {
   void doSomething();
   void somethingElse(String arg);
}


二、需要被代理的对象继承这个接口
Java code
?
1
2
3
4
5
6
7
8
9
10
public class RealObject implements Interface{
   @Override
    public void doSomething() {
       System.out.println("do something");
    }
   @Override
    public void somethingElse(String arg) {
        System.out.println("do some thing else "+arg);
   }
}

三、创建代理对象
创建代理对象有两种方式:一种静态代理,这种代理方式每个代理类只能为一个接口服务
另一种是动态代理,该种代理方式则能为多个接口服务

Java code
?
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
public class DynamicProxyHandler implements InvocationHandler{
     private Object proxied;
     /**
      * function:绑定委托对象并返回一个代理对象
      */
     public Object bind(Object proxied){
        this.proxied=proxied;
        //得到代理对象,传入参数:类加载器、接口列表、以及InvocationHandler的实现(这里是对象本身)
        return Proxy.newProxyInstance(proxied.getClass().getClassLoader(),
              proxied.getClass().getInterfaces(), this);
     
  
     @Override
     public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable { 
        //执行你想要的的操作
        System.out.println("****proxy: "+proxy.getClass()+". method:"+method+". args:"+args);
        if(args!=null){
            for(Object arg:args){
                System.out.println("args= "+arg);
            }
        }
       //可以对特定方法进行操作
        if(method.getName().equals("somethingElse")){
            System.out.print("SOME THINGELSE:");
        }
       //请求转发,调用被代理对象的方法 执行实际方法
        return method.invoke(proxied, args);
    }
}


四、测试
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SimpleDynamicProxy{
        public static void consumer(Interface iface){
            iface.doSomething();
            iface.somethingElse("bibo");
        }
        public static void main(String[] args){
            RealObject real = new RealObject();
            /*consumer(real);*/
            /**proxy:代理对象   real:被代理对象**/  
            DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler();
            Interface proxy = (Interface) dynamicProxyHandler.bind(real); 
            consumer(proxy);
        }
}

结果:
****proxy: class $Proxy0. method:public abstract void my.rtti.Interface.doSomething(). args:null
do something
****proxy: class $Proxy0. method:public abstract void my.rtti.Interface.somethingElse(java.lang.String). args:[Ljava.lang.Object;@47b480
args= bibo
SOME THINGELSE:do some thing else bibo

五、为什么要用动态代理
对于某些类不能直接访问的,则可以用动态代理作为中间角色;
要对某些对象调用过程中执行某些操作,或者进行分析;

六、java代理用处
例如 spring aop 、事务、日志等

七、java 代理和spring aop的关系
参考以下文章 http://blog.csdn.net/lirui0822/article/details/8555691
其他可以参考 http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html
0 0
原创粉丝点击