JDK动态代理,只能为接口创建动态代理
JDK的动态代理是通过java.lang.reflect.Proxy 和java.lang.reflect.InvocationHandler可以生成动态代理类或者代理对象
可以通过 java.lang.reflect.Proxy 来创建代理类或者代理实例:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader – 代理对象的类加载器,interfaces – 代理对象需要实现的接口,h 执行代理对象的每个方法时候会被替换执行h的invoke()方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
Person person1= new PersonImpl();
//创建一个InvocationHandler对象
InvocationHandler in = new MyInvokationHandler(proxy);
//使用指定的InvocationHandler来生成一个动态代理对象
Person person = (Person)Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Person.class}, in);
//返回动态代理的实例
Class<? extends InvocationHandler> aClass = Proxy.getInvocationHandler(person).getClass();
System.out.println(aClass.getName());
person.walk();
person.sayHello("荀公达");
}
}
interface Person {
void walk();
void sayHello(String name);
}
class PersonImpl implements Person {
@Override
public void walk() {
System.out.println(1);
}
@Override
public void sayHello(String name) {
System.out.println(2);
}
}
class MyInvokationHandler implements InvocationHandler {
private Object target;
public MyInvokationHandler(Object target) {
this.target = target;
}
/**
*
* @param proxy 代表动态代理对象
* @param method 代表正在执行的方法
* @param args 代表调用目标方法时传入的实参
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-------------正在执行的方法:" + method);
if (args != null) {
System.out.println("下面是执行方法时传入的实参为");
for (Object arg : args) {
System.out.println(arg);
}
} else {
System.out.println("调用该方法没有实参!");
}
return null;
}
}
proxy:代表动态代理对象
method:代表正在执行的方法
args:代表调用目标方法时传入的实参
在执行上面程序时候,debug发现,proxy的参数的值不是被代理对象,而是null
但是我在执行例子2时,proxy的值是被代理的对象
准备接口和接口的实现类
public interface Dog {
void info();
void run();
}
public class GunDog implements Dog {
@Override
public void info() {
System.out.println("一只猎狗");
}
@Override
public void run() {
System.out.println("奔跑的速度");
}
}
创建InvocationHandler的实现类
public class MyInvokationHandler implements InvocationHandler {
//需要被代理的对象
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
DogUtil dogUtil = new DogUtil();
//执行dogutil中第一个method方法
dogUtil.method();
//已target作为主调来执行method方法
Object result = method.invoke(target, args);
//执行dogutil中第二个method2方法
dogUtil.method2();
return result;
}
}
准备Proxy来生成动态代理类
public class MyProxyFactory {
public static Object getProxy(Object target) {
//创建一个MyInvokationHandler 对象
MyInvokationHandler myInvokationHandler = new MyInvokationHandler();
//为MyInvokationHandler设置target对象
myInvokationHandler.setTarget(target);
//创建并返回一个动态代理
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), myInvokationHandler);
}
}
测试
public class Test {
public static void main(String[] args) {
Dog gunDog = new GunDog();
Dog dog = (Dog)MyProxyFactory.getProxy(gunDog);
dog.info();
dog.run();
}
}
运行以上代码发现proxy的值是我想要的值,就是被代理对象