目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现
以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串并且输出方法的返回值。
1,定义一个产品的接口
package com.test.reflect;
public interface ProductInterface {
String getName();
}
2,定义产品实现接口
package com.test.reflect;
public class Product implements ProductInterface {
@Override
public String getName() {
System.out.println(" syso getName");
return "getName";
}
}
3,定义产品的代理类实现InvocationHandler接口
package com.test.reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProductProxy implements InvocationHandler {
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public ProductProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
System.out.println("proxy"+arg0.getClass());
if(arg2!=null){
for(Object object:arg2){
System.out.println(object);
}
}
Object result=null;
if(arg1!=null){
if(arg1.getName().equals("getName")){
System.out.println("before getName");//方法调用前
result=arg1.invoke(target,arg2);//方法的调用 注意调用的是目标target的方法
System.out.println("after getName");//方法调用后
}
}
return result;//返回方法的返回值
}
}
4,动态代理的测试
<pre name="code" class="java">package com.test.reflect;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
ProductInterface product=new Product();//定义产品
ProductInterface productInterface=(ProductInterface)Proxy.newProxyInstance(
product.getClass().getClassLoader(), //取得ClassLoader
product.getClass().getInterfaces(), //取得实现的接口
new ProductProxy(product));//设置代理把需要代理的产品放进去
System.out.println(productInterface.getName());//调用方法输出返回值
}
}
输出:
proxyclass com.sun.proxy.$Proxy0
before getName
syso getName
after getName
getName
总结:动态打理可以在方法执行前后加入其他的业务逻辑,这是AOP(面向切面)编程的实现原理,可以对面向对象编程进行很好的补充,jdk支持原生态的动态代理(被代理的类必须实现接口),还有其他的动态代理方法(cjlib)这里就不介绍了。