反射(6)--动态代理

动态代理

•    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。

•    举例:春季回家买票让人代买

•    动态代理:在程序运行过程中产生的这个对象

•    而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

创建动态代理

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);
构造方法:

protected

Proxy(InvocationHandler h)
使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例。

成员方法

static InvocationHandler

getInvocationHandler(Object proxy)
返回指定代理实例的调用处理程序。

static Class

getProxyClass(ClassLoader loader, Class... interfaces)
返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。

static boolean

isProxyClass(Class cl)
当且仅当指定的类通过 getProxyClass 方法或 newProxyInstance 方法动态生成为代理类时,返回 true。

static Object

newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

 

接口 InvocationHandler

接口 InvocationHandlerjava.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();

你可能感兴趣的:(java基础—反射)