代理模式——动态代理

原文链接:http://www.cnblogs.com/flyoung2008/archive/2011/10/06/2199160.html


动态代理其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。

  步骤如下:

  1、  首先获取一个业务接口的实现对象

     2、  获取一个InvocationHandler实现

    3、创建动态代理对象

  4、通过动态代理对象调用方法

  业务接口

package com.flyoung;

public interface HelloWorld {
    public void sayHello();
}

  业务接口实现

复制代码
package com.flyoung;

public class HelloWorldIml implements HelloWorld {

    public void sayHelloWorld() {
        System.out.println("Hello World!!!");

    }

}
复制代码

  InvocationHandler实现类

复制代码
package com.flyoung;

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

public class HelloWorldHandler implements InvocationHandler {
    private Object proxyObj;//要代理的对象
    public HelloWorldHandler(Object obj){
        this.proxyObj = obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result;
        result = method.invoke(this.proxyObj, args);
        return result;
    }

}
复制代码

  测试类

复制代码
package com.flyoung;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args) {
        HelloWorld hw = new HelloWorldIml();
        InvocationHandler handler = new HelloWorldHandler(hw);
        HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(hw.getClass().getClassLoader(),
                            hw.getClass().getInterfaces(), handler);
        proxy.sayHelloWorld();
    }

}
复制代码

扩展阅读:Java 动态代理机制分析及扩展

感觉原文的例子有问题,改了一下

通过动态代理实现简单的AOP。

基本思路:通过读取xml配置文件获取要被处理的对象,动态创建类的实例,并使用动态代理为该实例添加日志管理。

定义日志枚举类型

 

package com.flyoung;

public enum Level {
    INFO,DEBUG;
}

定义日志类

 

复制代码
package com.flyoung;

import java.util.Date;

public class Logger {
    public static void logging(Level level,String context){
        if(level.equals(Level.DEBUG)){
            System.out.println(new Date().toString()+""+context);
        }
        if(level.equals(Level.INFO)){
            System.out.println(new Date().toString()+""+context);
        }
    }
}
复制代码

业务接口

 

package com.flyoung;

public interface HelloWorld {
    public void sayHelloWorld();
}

业务接口实现

 

复制代码
package com.flyoung;

public class HelloWorldIml implements HelloWorld {

    public void sayHelloWorld() {
        System.out.println("Hello World!!!");

    }

}
复制代码

定义操作者接口

 

复制代码
package com.flyoung;

import java.lang.reflect.Method;
public interface Operation {
    public void start(Method method);
    public void end(Method method);
}
复制代码

实现操作者接口

 

复制代码
package com.flyoung;

import java.lang.reflect.Method;
public interface OperationImpl {
    public void start(Method method){
        //拦截器开始    
    }
 public void end(Method method){
        //拦截器结束
    }
 }
复制代码

实现InvocationHandler

 

复制代码
package com.flyoung;

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

public class ProxyHelloWorld implements InvocationHandler {
    Object operation;//操作者
    Operation delegate;//要处理的对象
    
    public Object bind(Object delegate,Operation operation){
        this.delegate=delegate;
        this.operation=operation;
        return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(),
                                      this.delegate.getClass().getInterfaces(), this);
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result=null;
        operation.start();//执行start方法
        //执行要处理对象方法
        result=method.invoke(this.delegate, args);
        operation.end();//执行end方法
        return result;
    }

}
复制代码

xml配置文件

 

<?xml version="1.0" encoding="UTF-8"?>
<package>
    <action name="hello" class="com.flyoung.HelloWorldIml"></action>
</package>

使用dom4j读取xml配置文件

 

复制代码
package com.flyoung;

import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element; 
import org.dom4j.Attribute;


import java.util.Iterator;
import java.util.List;
import java.io.File; 
import java.util.Map;
import java.util.HashMap;

public class TestDom4j {
    /**
     * 获取指定xml文档的Document对象,xml文件必须在classpath中可以找到
     *
     * @param xmlFilePath xml文件路径
     * @return Document对象
     */ 
    public static Document parse2Document(String xmlFilePath){
        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(new File(xmlFilePath));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return doc;
    }
    
    public static Map testParseXmlData(String xmlFilePath){
        //获取xml解析器对象
        //SAXReader reader = new SAXReader();
        //将xml解析为Document对象
        Document doc = TestDom4j.parse2Document(xmlFilePath);
        //获取文档的根元素
        Element root  = doc.getRootElement();
        //定义保存xml数据的缓冲字符串
        //StringBuffer sb = new StringBuffer();
        //定义保存属性、值的map
        Map<String,String> map = new HashMap<String,String>();
        for(Iterator i_action=root.elementIterator();i_action.hasNext();){
            Element e_action = (Element)i_action.next();
            for(Iterator a_action=e_action.attributeIterator();a_action.hasNext();){
                Attribute attribute = (Attribute)a_action.next();
                //sb.append(attribute.getName()+":"+attribute.getValue());
                //sb.append("\n");
                map.put(attribute.getName(), attribute.getValue());
            }
        }
        //System.out.println(sb);
        return map;
        
    }
    public static void main(String[] args) {
        Map map = TestDom4j.testParseXmlData("E:/workspace/Dom4j/test.xml");
        String className =(String)map.get("class");
        try {
            Class c = Class.forName(className);
            HelloWorld hw =(HelloWorld) c.newInstance();
            hw.sayHelloWorld();    
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {    
            e.printStackTrace();
        }
    }

}
复制代码

测试类

 

复制代码
package com.flyoung;

import java.util.Map;

public class Test {
    public static void main(String[] args) {
        Map map = TestDom4j.testParseXmlData("E:/workspace/Dom4j/test.xml");
        String className =(String)map.get("class");
        try {
            Class c = Class.forName(className);
            HelloWorld hw =(HelloWorld) c.newInstance();
            //hw.sayHelloWorld();    
            HelloWorld h = (HelloWorld)new ProxyHelloWorld().bind(hw, new OperationIml());
            h.sayHelloWorld();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {    
            e.printStackTrace();
        }
    }
}
复制代码

测试结果

 

Thu Oct 06 14:14:20 CST 2011 sayHelloWorld---start---
Hello World!!!
Thu Oct 06 14:14:20 CST 2011 sayHelloWorld---end---

下面要做的是回去读spring源码。












 

  

作者: 像少年啦飞驰
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值