Java 动态代理类
java动态代理类位于java.lang.reflect包下
Interface InvocationHandler
该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)
参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组
这个抽象方法在代理类中动态实现。
Proxy:该类即为动态代理类
-
Protected Proxy(InvocationHandler h)
- 构造函数,用于给内部的h赋值
-
Static Class getProxyClass (ClassLoader loader,Class[] interfaces)
- 获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组
-
Static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
- 返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)
-
Dynamic Proxy
- 它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
动态代理步骤:
1.创建被代理的类以及接口
package com.lxq.mybatis.learn.jdkProxy;
/**
* @Author Lxq
* @Date 2020/3/1 16:47
* @Version 1.0
*/
public interface GoodService {
/**
*
* @param goodName
* @param price
* @return
*/
String sale(String goodName,Integer price);
}
2. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法
package com.lxq.mybatis.learn.jdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @Author Lxq
* @Date 2020/3/1 16:48
* @Version 1.0
*/
public class GoodInvocation implements InvocationHandler {
private Class<?> mapperInterface;
public GoodInvocation(Class<?> mapperInterface) {
this.mapperInterface = mapperInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getClass())) {
return method.invoke(this,args);
}
System.out.println("调用前");
//这里是为接口的方法构造实现逻辑,
// 由于我们已经获取到了方法名称和参数值,所以可以根据实际需要去创建实现逻辑。
Object result = "方法名称:" + method.getName() + ",参数值:" + Arrays.toString(args) + ",clazz:" + mapperInterface;
System.out.println("调用后result:" + result);
return result;
}
}
3.通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
通过代理调用方法
package com.lxq.mybatis.learn.jdkProxy;
import java.lang.reflect.Proxy;
/**
* @Author Lxq
* @Date 2020/3/1 16:54
* @Version 1.0
*/
public class ProxyTest {
public static void main(String[] args) {
Class<GoodService> goodServiceClass = GoodService.class;
GoodInvocation invocation = new GoodInvocation(goodServiceClass);
GoodService proxyInstance = (GoodService)Proxy.newProxyInstance(goodServiceClass.getClassLoader(), new Class[]{goodServiceClass}, invocation);
String good = proxyInstance.sale("good", 5);
System.out.println("result=" + good);
}
}