Java实现动态代理
java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
(1)invocationhandler:该接口中仅定义了一个方法
public object invoke(object obj,method method, object[] args)
在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。 这个抽象方法在代理类中动态实现。
(2)proxy:该类即为动态代理类,作用类似于上例中的proxysubject,其中主要包含以下内容protected proxy(invocationhandler h):构造函数,用于给内部的h赋值。
static class getproxyclass (classloader loader, class[] interfaces)
获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
static object newproxyinstance(classloader loader, class[] interfaces, invocationhandler h)
返回代理类的一个实例,返回后的代理类可以当作被代理类使 用(可使用被代理类的在subject接口中声明过的方法)
所谓dynamic proxy是这样一种class:它是在运行时生成的class,在生成它时你必须 提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把 该class的实例当作这些interface中的任何一个来用。当然,这个dynamic proxy其实 就是一个 proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它 接管实际的工作。
在使用动态代理类时,我们必须实现invocationhandler接口:
参见程序 subject.java
参见程序 realsubject.java
参见程序 dynamicsubject.java
参见程序 client.java
package com.langsin.dynamicproxy;
//抽象角色(之前是抽象类,此处应改为接口):
public interface subject
{
abstract public void request();
}
package com.langsin.dynamicproxy;
//具体角色
public class realsubject implements subject
{
public realsubject()
{
}
public void request()
{
system.out.println("from real subject.");
}
}
package com.langsin.dynamicproxy;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
//代理处理器
/**
* 该代理类的内部属性为object类,实际使用时通过该类的构造函数dynamicsubject(object obj)对其赋值;
* 此外,在该类还实现了invoke方法,该方法中的 method.invoke(sub,args);
* 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,
* args为执行被代理对象相应操作所需的参数。
* 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
*/
public class dynamicsubject implements invocationhandler
{
private object sub;
public dynamicsubject()
{
}
public dynamicsubject(object obj)
{
sub = obj;
}
public object invoke(object proxy, method method, object[] args) throws throwable
{
system.out.println("before calling " + method);
method.invoke(sub, args);
system.out.println("after calling " + method);
return null;
}
}
package com.langsin.dynamicproxy;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.proxy;
//客户端
public class client
{
static public void main(string[] args) throws throwable
{
realsubject rs = new realsubject(); // 在这里指定被代理类
invocationhandler ds = new dynamicsubject(rs);
class<?> cls = rs.getclass();
// 以下是一次性生成代理
subject subject = (subject) proxy.newproxyinstance(
cls.getclassloader(), cls.getinterfaces(), ds);
subject.request();
}
}
实例2:
package com.langsin.dynamicproxy;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
import java.lang.reflect.proxy;
import java.util.list;
import java.util.vector;
public class vectorproxy implements invocationhandler
{
private object proxyobj;
public vectorproxy(object obj){
proxyobj = obj;
}
public static object factory(object obj){
class<?> cls = obj.getclass();
return proxy.newproxyinstance(cls.getclassloader(), cls.getinterfaces(), new vectorproxy(obj));
}
public object invoke(object proxy, method method, object[] args) throws throwable{
system.out.println("before calling " + method);
if (args != null){
for (int i = 0; i < args.length; i++){
system.out.println(args[i] + "");
}
}
object object = method.invoke(proxyobj, args);
system.out.println("after calling " + method);
return object;
}
@suppresswarnings("unchecked")
public static void main(string[] args){
list<string> v = (list<string>) factory(new vector<string>(10));
v.add("new");
v.add("york");
system.out.println(v);
v.remove(0);
system.out.println(v);
}
}
实例3、
package com.langsin.dynamicproxy;
public interface foo{
void doaction();
}
package com.langsin.dynamicproxy;
public class fooimpl implements foo{
public fooimpl(){
}
public void doaction(){
system.out.println("in fooimp1.doaction()");
}
}
package com.langsin.dynamicproxy;
public class fooimpl2 implements foo{
public fooimpl2(){
}
public void doaction(){
system.out.println("in fooimp2.doaction()");
}
}
package com.langsin.dynamicproxy;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
public class commoninvocationhandler implements invocationhandler{
// 动态执行对象,需要回调的对象
private object target;
// 支持构造子注射
public commoninvocationhandler(){
}
// 支持构造子注射
public commoninvocationhandler(object target){
settarget(target);
}
/**
*
* 采用setter方法注射
*
* @param target
*
*/
public void settarget(object target){
this.target = target;
}
/**
*
* 调用proxy中指定的方法method,并传入参数列表args
*
* @param proxy
* 代理类的类型,例如定义对应method的代理接口
*
* @param method
* 被代理的方法
*
* @param args
* 调用被代理方法的参数
*
* @return
*
* @throws java.lang.throwable
*
*/
public object invoke(object proxy, method method, object[] args) throws throwable{
return method.invoke(target, args);
}
}
package com.langsin.dynamicproxy;
import java.lang.reflect.proxy;
public class demo{
public static void main(string[] args){
// 1.通用的动态代理实现
commoninvocationhandler handler = new commoninvocationhandler();
foo f;
// 2.接口实现1
handler.settarget(new fooimpl());
// 方法参数说明:代理类、代理类实现的接口列表、代理类的处理器
// 关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法
// 如果代理类没有实现指定接口列表,会抛出非法参数异常
f = (foo) proxy.newproxyinstance(foo.class.getclassloader(),
new class[] { foo.class },
handler);
f.doaction();
// 3.接口实现2
handler.settarget(new fooimpl2());
f = (foo) proxy.newproxyinstance(foo.class.getclassloader(),
new class[] { foo.class },
handler);
f.doaction();
}
}
由于本人文采有限,所以大部分内容都是代码,还请大家谅解^_^