动态代理例子改进
在“反射包 java.lang.reflect⑤ 之 Java 中 Proxy 动态代理类 探秘(一)” 中已经简单地实现了一个动态代理的例子。但是这个例子有没有觉得别扭呢。
我们这个 动态代理类中的获取代理的接口:
TargetInterface getProxy(TargetInterface
target
)
似乎和要代理的接口耦合得过分了。也就是说它只能代理
TargetInterface 这个接口的实现类,其他接口的他不行。那么想要可以代理其他接口,其实只需要把里面的接口改为Object 就可以了。下面以一个全新的例子来说明。
代理的接口
package com.hlm.reflect.proxy.inteface;
public
interface
Animal
{
/**
* 吃
*
@param
str
*/
public
void
eat(String
str
);
/**
* 跑
*
@param
str
*/
public
void
run(String
str
);
/**
* 睡
*
@param
str
*/
public
void
sleep(String
str
);
}
两个实现类
package
com.hlm.reflect.proxy.impl;
import
com.hlm.reflect.proxy.inteface.Animal;
public
class
Cat
implements
Animal {
public
void
eat(String
str
) {
System.
out
.println(
"我是一只猫,我在吃"
+
str
);
}
public
void
run(String
str
) {
System.
out
.println(
"我是一只猫,我在跑去"
+
str
);
}
public
void
sleep(String
str
) {
System.
out
.println(
"我是一只猫,我在睡觉啦!"
);
}
}
package com.hlm.reflect.proxy.impl;
import
com.hlm.reflect.proxy.inteface.Animal;
public
class
Dog
implements
Animal {
public
void
eat(String
str
) {
System.
out
.println(
"我是一只狗,我在吃"
+
str
);
}
public
void
run(String
str
) {
System.
out
.println(
"我是一只狗,我在跑去"
+
str
);
}
public
void
sleep(String
str
) {
System.
out
.println(
"我是一只狗,我在睡觉啦!"
);
}
}
下面是代理类
package com.hlm.reflect.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.apache.log4j.Logger;
public class CopyOfTargetProxy {
private Object targetObj ;
/**
* 用于记录日志
*/
Logger log = Logger.getLogger(CopyOfTargetProxy.class);
/**
* 通过全限定类名获取代码对象的方法
* @param className :全限定类名
* @return
* @throws ClassNotFoundException
* @throws IllegalArgumentException
*/
public Object getProxy(Object target ) throws IllegalArgumentException, ClassNotFoundException{
this.targetObj = target;
//使用代码类Proxy创建className的对象,并且为其每个方法设置日志记录
return Proxy.newProxyInstance(CopyOfTargetProxy.class.getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
log.info("日志开始:"+method.getName()+"方法开始执行啦!");
Object obj = method.invoke(targetObj, args);
log.info("日志结束:"+method.getName()+"方法结束执行啦!");
return obj;
}
});
}
}