zoukankan      html  css  js  c++  java
  • 代理模式——动态代理

      动态代理其实现主要通过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源码。












      

  • 相关阅读:
    10个有用的网站访问分析工具
    在 IIS6 ASP.NET 4.0 安装 最常遇到的四个问题
    [转]qUIpt:JavaScript Cache Library
    Windows Phone 7 Jump Start
    TFS GrantBackup Plan Permissions Error
    JQuery 专题
    IEnumberable<String> To String
    Charts Controls 开发系列2
    Script#
    SQL SERVER 经验、资料收录
  • 原文地址:https://www.cnblogs.com/flyoung2008/p/2199160.html
Copyright © 2011-2022 走看看