动态代理中,不需要手动创建代理类,实际应用有AOP:
1、定义一个接口Person
public interface Person {
void payMoney();
}
2、定义一个委托类,实现Person接口:
public class Student implements Person {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void payMoney() {
System.out.println(name + ": pay 100");
}
}
3、Java提供Proxy类和InvocationHandler接口,生成动态代理类,动态代理的原理为java的反射机制,在原有的student的payMoney上添加切面逻辑,定义Utils方法:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class StuProxyHandler<T> implements InvocationHandler {
private T target;
public StuProxyHandler(T target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Utils.start(method);
Object object = method.invoke(target, args);
Utils.finish();
return object;
}
}
Utils工具类:
import java.lang.reflect.Method;
public class Utils {
private static long start;
public static void start(Method method) {
System.out.println("method " + method.getName() + ": start running");
start = System.currentTimeMillis();
}
public static void finish() {
try {
Thread.sleep(500);
System.out.println("It cost:" + (System.currentTimeMillis() - start + "ms"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4、测试动态代理:
import static org.junit.jupiter.api.Assertions.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import org.junit.jupiter.api.Test;
public class TestDymProxy {
@Test
public void test() {
Person person = new Student("jack");
InvocationHandler stuProxy = new StuProxyHandler<Person>(person);
Person stu = (Person)Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuProxy);
stu.payMoney();
}
}
查看输出结果:
method payMoney: start running
jack: pay 100
It cost:501ms
结论:动态代理的内部会创建一个Proxy*的代理类,只能对接口进行动态代理,无法对单个类进行动态代理。