Java语言的动态代理

方便起见,  根据孙鑫的一个例子来学习,先看代码: 

ILogin接口

public   interface  ILogin
{
    
public boolean login(String username,String password);
}

 

ILogin接口的实现类(即被代理类):

public   class  LoginAction  implements  ILogin
{
    
public boolean login(String username,String password)
    
{
        
if("zhangsan".equals(username))
            
throw new RuntimeException();
        
else if("lisi".equals(username) && "1234".equals(password))
        
{
            
return true;
        }

        
else
        
{
            
return false;
        }

    }

}

 

代理类:

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

import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;

public   class  LoginHandler  implements  InvocationHandler
{
    
private Object targetObject;
    
    Log log
=LogFactory.getLog(LoginHandler.class);
    
public Object bind(Object targetObject)
    
{
        
this.targetObject=targetObject;
        
return Proxy.newProxyInstance(
                targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(),
                
this);
        
    }

    
    
public Object invoke(Object proxy, Method method, Object[] args)
            
throws Throwable
    
{
        
if(ILogin.class.isAssignableFrom(targetObject.getClass()))
        
{
            String username
=(String)args[0];
            
            String methodName
=method.getName();
            
if("login".equals(methodName))
            
{
                log.info(
"user" + " ["+username+"] is logining");
            
                
boolean bFlag=(Boolean)method.invoke(targetObject,args);
                
                
if(bFlag)
                    log.info(
"user" + " ["+username+"] login success");
                
else
                    log.info(
"user" + " ["+username+"] login failed");
                
return bFlag;
            }

        }

        
return method.invoke(targetObject,args);
    }


}

测试方法:

public   void  testDynamicProxy()
    
{
        LoginHandler handler
=new LoginHandler();
        
    
        ILogin login
=(ILogin)handler.bind(new LoginAction());
        
        login.login(
"zhangsan","1234");
        
    }

 

实现一个动态代理类,首先要实现InvocationHandler接口,这个接口只有一个invoke方法:


  
  
Object invoke(Object proxy,Method method,Object[] args) throws  Throwable

 参数解释:

proxy:代理对象,

method:对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。

args:包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null

接着,还要写一个方法用于绑定被代理对象,方法的名字可以自己定义,这里为bind:

public  Object bind(Object targetObject)
    
{
        
this.targetObject=targetObject;
        
return Proxy.newProxyInstance(
                targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(),
                
this);
        
    }

说一下Proxy的newProxyInstance静态方法:(这种方法是为被代理对象创建一个代理对象,这种产生代理的方法是动态的,所以称作动态代理)

public   static  Object newProxyInstance(ClassLoader loader,Class <?> [] interfaces, InvocationHandler h)
                               
throws  IllegalArgumentException

参数:

loader:被代理对象的类加载器,以加载代理对象。

interfaces:被代理对象实现的接口

h:指派方法调用的调用处理程序

这种方法只能对接口进行代理,如果被代理类的方法在接口里没有定义,则这个方法不能被代理执行。

一个代理对象调用一个方法(Ilogin接口里的任何一个方法)的时候,实现InvocationHandler的类的invoke的方法首先被调用,如果不同的方法需要代理的功能都不同(本例的代理功能是添加登录验证),那就需要在invoke方法里做判断,这样使用代理就没有什么优势了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值