动态代理
动态代理:是实现增强类中的一种方式,jdk中的动态代理:Proxy对象,使用最广泛的是在AOP切面编程中。
实现一个简单的动态代理来了解其中的运行机制。
创建一个接口:Person类型的接口
public interface Person{ public abstract void eat();
public abstract void sleep();
public abstract String getName();
}
创建一个类(Student)来实现Person接口
public class Student implements Person{ private String name; public Student(String name) { this.name=name; } @Override public void eat() { System.out.println("吃串串"); } @Override public void sleep() { System.out.println("正在睡觉...."); } @Override public String getName() { return name; } }
为了在学生吃串串前来杯啤酒我们需要来增强Student
三种方式:
1.继承
2.装饰类
3.动态代理
这里使用动态代理类:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyStudent implements InvocationHandler { private Person p; public ProxyStudent(Person p) { this.p=p; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("吃炸鸡"); p.eat();
String name=p.getName(); System.out.println("喝啤酒"); return name; } }
测试类:
import java.lang.reflect.Proxy; public class TestDemo { public static void main(String[] args) { Person p=new Student(); Person ps=(Person) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), new ProxyStudent(p)); ps.eat();
String name=ps.getName();
System.out.println(name);
}
}
输出结果:
吃炸鸡 吃串串 喝啤酒 吃炸鸡 吃串串 喝啤酒 张三
这个动态类不是特别灵活,我们进一步修改代理类
我们需要知道其中的三个参数(Object proxy, Method method, Object[] args)
参数一:proxy:动态代理对象
参数二:method:表示需要执行的方法
参数三:args:表示执行方法参数
package com.baidu;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyStudent implements InvocationHandler {
private Person p;
public ProxyStudent(Person p) {
this.p=p;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("吃炸鸡");
Object object = method.invoke(p, args);
System.out.println("喝啤酒");
return object;
}
}
如果我们需要在某个特殊方法进行增强我们可以判断它执行的方法;
只在吃串串前进行增强
package com.baidu;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyStudent implements InvocationHandler {
private Person p;
public ProxyStudent(Person p) {
this.p=p;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("eat".equalsIgnoreCase(method.getName())) {
System.out.println("吃炸鸡");
method.invoke(p, args);
System.out.println("喝啤酒");
return null;
}
Object object = method.invoke(p, args);
return object;
}
}
输出结果:
吃炸鸡
吃串串
喝啤酒
张三