Java回炉之反射(二)动态代理
不用代理的情况
首先假设有一个操作接口DemoDao
及其实现类DemoImpl
。再来一个用来演示的调用者Main
。
- DemoDao.java
//首先定义一个操作接口,带一个method方法:返回String类型,参数String类型。
public interface DemoDao {
public abstract String method(String arg);
}
- DemoImpl.java
//定义操作接口的实现类,重写method方法:根据参数输出一句话,并返回参数处理后的结果。
public class DemoImpl implements DemoDao{
@Override
public String method(String arg) {
System.out.println("run method with arg:"+arg);
return "result by arg:"+arg;
}
}
- Main.java
//实例化一个操作对象,并调用其method方法。
public class Main {
public static void main(String[] args) {
DemoDao dao=new DemoImpl();
System.out.println("<--run demo without proxy-->");
dao.method("demo");
System.out.println("<-->");
}
}
- 结果输出:
<--run demo without proxy-->
run method with arg:demo
<-->
使用动态代理
在上述基础之上,写一个代理类DemoHandler
实现InvocationHandler
接口,然后在Main
中使用该代理。
- DemoHandler.java
public class DemoHandler implements InvocationHandler{
/**被代理的对象*/
private Object target;
/**构造方法中指定被代理的对象*/
public DemoHandler(Object target){
this.target=target;
}
/**重写接口方法*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("pre method");
//调用target的method方法,传入args参数,接收返回值result
Object result = method.invoke(target, args);
System.out.println("after method");
return result;
}
}
- 修改Main.java如下
public class Main {
public static void main(String[] args) {
DemoDao dao=new DemoImpl();
System.out.println("<--run demo without proxy-->");
dao.method("demo");
System.out.println("<-->");
System.out.println("<--run demo with proxy-->");
//构建代理
DemoHandler handler=new DemoHandler(dao);
DemoDao daoProxy = (DemoDao)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), handler);
//调用方法并接收返回值
String result = daoProxy.method("proxy");
System.out.println(result);
System.out.println("<-->");
}
}
- 结果输出:
<--run demo with proxy-->
pre method
run method with arg:proxy
after method
result by arg:proxy
<-->
- 查看完整源代码