动态代理的话分为jdk的动态代理和cglib动态代理,jdk的动态代理是基于接口实现的,意思就是,要代理的类必须实现某个接口作为代理模型,而cglib则是直接基于类进行动态代理,今天主要讲jdk的动态代理,后边再对cglib进行拓展(好多同学不明白动态代理的目的,其实就是在不修改源代码的前提下对方法进行拓展,如果我可以保存方法的操作日志,或者打印方法的执行时间等等)
1.首先要了解jdk动态代理最重要的一个api,Proxy类下的
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException{
……
}
对每个参数进行简单的讲解,第一个就是使用哪个类加载器对代理类进行加载, 第二个参数就是指定代理的接口,就是说以哪个接口为模型就带代理拓展,也就是说代理的类有哪些方法,第三个参数就是指定具体的代理类执行的拓展方法逻辑
2.创建要代理的接口模型,意思就是根据接口中定义的方法进行代理
//接口1
public interface Animal {
void wakeup();
void sleep();
}
//实现类1
public class Cat implements Animal {
private String name;
public Cat() {
}
public Cat(String name) {
this.name = name;
}
@Override
public void wakeup() {
System.out.println("小猫"+name+"早晨醒来啦");
}
@Override
public void sleep() {
System.out.println("小猫"+name+"晚上睡觉啦");
}
}
//实现类2
public class Dog implements Animal {
private String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
@Override
public void wakeup() {
System.out.println("小狗"+name+"早晨醒来啦");
}
@Override
public void sleep() {
System.out.println("小狗"+name+"晚上睡觉啦");
}
}
3.创建代理类,就是定义具体的方法拓展
//代理类
public class JDKDynamicProxy implements InvocationHandler {
private Object bean;
public JDKDynamicProxy(Object bean) {
this.bean=bean;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodname=method.getName();
if (methodname.equals("wakeup")){
System.out.println("早安~~~");
}else if(methodname.equals("sleep")){
System.out.println("晚安~~~");
}
return method.invoke(bean,args);
}
}
4.编写测试类
//测试类
public class TestJDKDynamicProxy {
public static void main(String[] args) {
JDKDynamicProxy proxy = new JDKDynamicProxy(new Student("张三"));
//创建代理实例
Person student = (Person) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Person.class}, proxy);
student.wakeup();
student.sleep();
proxy = new JDKDynamicProxy(new Doctor("王教授"));
Person doctor = (Person) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Person.class}, proxy);
doctor.wakeup();
doctor.sleep();
}
}