动态代理
• 代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
• 举例:春季回家买票让人代买
• 动态代理:在程序运行过程中产生的这个对象
• 而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理
创建动态代理
l 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
l Proxy类中的方法创建动态代理类对象
• public static Object newProxyInstance(ClassLoaderloader,Class<?>[] interfaces,InvocationHandler h)
• 最终会调用InvocationHandler的方法
• InvocationHandler
l Object invoke(Objectproxy,Method method,Object[] args)
Proxy类和InvocationHandler接口
类 Proxy
类 Proxy在java.lang.reflect包中,Proxy
提供用于创建动态代理类和实例的静态方法。
创建某一接口 Foo
的代理:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
构造方法:
| Proxy |
成员方法
| getInvocationHandler |
| getProxyClass |
| isProxyClass |
| newProxyInstance |
接口 InvocationHandler
接口 InvocationHandler在java.lang.reflect包中,InvocationHandler
是代理实例的调用处理程序 实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke
方法。
成员方法
Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
参数:
proxy - 在其上调用方法的代理实例
method - 对应于在代理实例上调用的接口方法的 Method 实例。
args
- 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为null
。
返回:从代理实例的方法调用返回的值。
实例:动态代理权限校验和添加日志
实现InvocationHandler接口
编写MyInvocationHandler.java:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
publicclassMyInvocationHandler implementsInvocationHandler {
private Object target; // 目标对象
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验");
Object result = method.invoke(target, args);
System.out.println("日志记录");
return result; // 返回的是代理对象
}
}
创建动态代理
StudentDao sd = new StudentDaoImpl();
MyInvocationHandler handler2 = newMyInvocationHandler(sd);
StudentDao proxy = (StudentDao)Proxy.newProxyInstance(sd.getClass().getClassLoader(),sd.getClass().getInterfaces(),handler2);
proxy.login();
proxy.regist();