代理模式——动态代理

寵の児 提交于 2019-11-27 15:16:03

  动态代理其实现主要通过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 Operation {    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 proxy;//操作者    Object delegate;//要处理的对象        public Object bind(Object delegate,Object proxy){        this.delegate=delegate;        this.proxy=proxy;        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;        //反射得到操作者的class        Class c = this.proxy.getClass();        Method start = c.getDeclaredMethod("start", new Class[]{Method.class});        //反射执行start方法        start.invoke(this.proxy, new Object[]{method});        //执行要处理对象方法        result=method.invoke(this.delegate, args);        //发射执行end方法        Method end = c.getDeclaredMethod("end", new Class[]{Method.class});        end.invoke(this.proxy, new Object[]{method});        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源码。












 

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!