动态代理

来源:互联网 发布:python 字符串连接 编辑:程序博客网 时间:2024/05/05 03:55


//在接触动态代理之前,首先你要先知道一些反射知识,这样方便理解动态代理。
package com.reflectProxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MyReflectProxy {
        private Class clazz;    //对象所属的类     
        private Object target;  //目标对象     
        private Method method;  //目标方法     
        
        public void target(Object target){
             this.target = target;            //设置目标对象
             this.clazz = target.getClass();  //设置目标对象类 
        }
        
        public Object doMethod(String methodName){
            return doMethod(methodName,null);
        }
        
        //执行方法
        public Object doMethod(String methodName, Object ... params) {   //类似数组用法,无限制大小    
           
            //重新设置目标方法的参数
            Class[] paramTypes = null;
            
            //将方法的对象参数数组转为对应的类参数数组
            if(params!=null){  
                paramTypes = new Class[params.length];     
                for(int i = 0 ; i < params.length ; i ++ ) {     
                    paramTypes[i] = params[i].getClass();     
                }
            }       
         
            try {
                //利用反射机制得到方法对象
                this.method = clazz.getMethod(methodName, paramTypes);  //第二个参数为Class类型
                //执行该方法
                return this.method.invoke(target, params);
                
            } catch (NoSuchMethodException | SecurityException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e) {    
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {    
                e.printStackTrace();
            }
            return null;
        }    
}

//测试调用,使用反射来对对象操作
package com.reflectProxy;
import com.entity.Student;
/**
 * 用反射方法操作对象
 * @author qiugaoying
 */
public class Application {
    public static void main(String[] args) {
        Student s=new Student();
        
        MyReflectProxy mf=new MyReflectProxy();
        mf.target(s);
        mf.doMethod("setStuName""小高");
        mf.doMethod("setStuAge",19);
        System.out.println("name:"+ mf.doMethod("getStuName")+"age:"+mf.doMethod("getStuAge"));
        
    }
}


/*----------------------------------动态代理-----------------------------------*/

//准备一个接口
package com.Proxy;
public interface Account {
   
    // 查看账户方法
    public void queryAccount();
    // 修改账户方法
    public String updateAccount(String name, String pwd);    
    
}

//接口实现类
package com.Proxy;
public class AccountImp implements Account {
    @Override
    public void queryAccount() {
        System.out.println("查询账号--------");
    }
    @Override
    public String updateAccount(String name, String pwd) {
        System.out.println("更新账号---------");
        pwd="000000";
        return name+","+pwd;
    }
}

//代理类
package com.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 动态代理类
 * @author qiugaoying
 * 该动态代理利用反射机制,动态获得任何对象的任何方法, 只能代理实现接口的类。
 * java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力
 */
public class DynamicProxy implements InvocationHandler{
    private Object target;

    //绑定对象
    public Object target(Object target){
        this.target=target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);   //返回一个代理对象
    }
    
    
    //动态调用方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        Object obj=null;
        beforeMethod();//执行前
        obj= method.invoke(target, args);
        afterMethod(); //执行后
        return obj;
    }
    
    private void beforeMethod(){
        System.out.println("事务开始...");
    }
    private void afterMethod(){
        System.out.println("事务结束...");
    }
    
}


//动态代理 测试
package com.Proxy;
/**  利用动态代理来执行
 * @author qiugaoying
 */
public class Application {
    public static void main(String[] args) {
        Account ac=new AccountImp();
        DynamicProxy dp=new DynamicProxy(); //准备一个代理
        
       //绑定代理对象
        ac=(Account) dp.target(ac); 
        ac.queryAccount();        
    
       //有参数
       String newPwd=ac.updateAccount("小雪""123456");
       System.out.println(newPwd);
    }
}

总结:生活中处处充满代理。卖房子的中介所。体育明星的经济人。玩游戏的代理者。等等。 程序中,代理类利用反射机制,实现了任何类任何方法的代理,可谓之强大,在第一次学完代理模式,我只是在停留在静态代理上,认为代理模式和装饰模式差不多,经过此番动态代理的深入学习,体会代理类之强大,这让程序员更加专注于业务上。代理模式可让所有的类都给封装了相同的前后处理方法。而装饰模式是给一个类包装不同的方法。
2012-12-16  小高

0 0