定义接口:
接口就相当于桥梁
package com.dynamic.proxy;
public interface ProxyInterface {
public void sayHello();
public void sayBye();
}
定义被代理类:
被代理类就是会被增强功能的方法
public class ProxyInterfaceImpl implements ProxyInterface {
@Override
public void sayHello() {
System.out.println("Hello!");
}
@Override
public void sayBye(){
System.out.println("Good Bye!");
}
}
定义处理器:
package com.dynamic.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyProxyInvocationHandler implements InvocationHandler {
/**
* 定义被代理的对象
*/
private Object proxied = null;
/**
* 构造器, 在创建MyInvocationHandler对象时,传入要被代理的对象
*/
public MyProxyInvocationHandler(Object proxied){
this.proxied = proxied;
}
/**
* 所有代理接口的实现类对象的方法在调用时,都会执行invoke方法
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 对方法进行增强,如对方法sayHello()进行增强
*/
Object rtInvoke = null;
if(method.getName().equals("sayHello")){//先判断方法名是否为sayHello
System.out.println("前置处理:Sally...");
rtInvoke = method.invoke(proxied, args);
System.out.println("后置处理:3Q....");
}
return rtInvoke;
}
}
测试动态代理功能:
package com.dynamic.proxy;
import com.dynamic.proxy.impl.ProxyInterfaceImpl;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
public class ProxyClient {
@Test
public void test() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("------第一种-------");
/**
* 测试两种方式
*/
/*第一种
* (5)代理对象调用目标函数
* */
// (1)先获取代理类$Proxy0的class文件, 也可以不写
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// (2)加载动态代理类(传入要被代理的接口数组, 即要代理哪些接口)
Class proxyClass = Proxy.getProxyClass(ProxyInterface.class.getClassLoader(), ProxyInterface.class);
// (3)通过代理类获取到代理类的构造函数,Proxy的构造函数中,有参构造函数为Proxy(InvocationHandler),因此要给构造函数一个
// InvocationHandler.class类型的参数类型
Constructor cst = null;
try {
cst = proxyClass.getConstructor(InvocationHandler.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// (4)通过构造函数传入自定义的InvocationHandler对象,生产代理对象
// 先获取被代理对象,再将被代理对象交给自定义的MyInvocationHandler对象
// 最后将MyInvocationHandler对象传入代理类的构造器,完成代理对象的创建
// 最后将代理对象强转为接口类型
// 为什么能强转????因为通过jvm生成的代理对象(反编译javap查看),实现了代理接口
// 另外,生成的代理类同时继承了Proxy类,并且调用了invoke(,)方法,这个方法便是MyInvocationHandler中
// 我们自定义的InvocationHandler,也就调用了自定义的sayHello方法
ProxyInterfaceImpl proxyInterfaceimpl = new ProxyInterfaceImpl();
MyProxyInvocationHandler myProxyInvocationHandler = new MyProxyInvocationHandler(proxyInterfaceimpl);
ProxyInterface proxyintfs = null;
try {
proxyintfs = (ProxyInterface) cst.newInstance(myProxyInvocationHandler);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
proxyintfs.sayHello();
}
});
t1.start();
try {
t1.join();
}catch (InterruptedException e){
e.printStackTrace();
}
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
/**
* 第二种, 直接调用Proxy类的静态方法
*/
System.out.println("------第二种-------");
//要被代理的接口, 传入的接口为数组类型,与上面第一种情况定义的可变参数不同(即...表示0个或多个可变Object参数)
ProxyInterface proxyIntfs = (ProxyInterface) Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),
new Class[] {ProxyInterface.class}, new MyProxyInvocationHandler(new ProxyInterfaceImpl()));
proxyIntfs.sayHello();
}
});
t2.start();
try {
t2.join();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}