提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、概述
1.
jdk动态代理的实现:
在反射包:java.lang.reflect,里面有三个类:InvocationHandler,Method,Proxy
InvocationHandler接口(调用处理器):里面只有一个方法invoke()
代理类需要完成的目标:1.调用目标方法,执行目标方法的功能 2.重写invoke()方法,增添新的功能,实现功能增强
- public Object invoke(Object proxy,Method method,Object[] args):
- Object proxy:jdk创建的代理对象,无需赋值
- Method method:目标类中的方法,jdk提供method对象
- Object[] args:目标类中的参数,jdk提供
使用方式:
- 创建类实现接口Invocationhandler
- 重写invoke()方法,把原来静态代理对象中代理类要完成的功能写在这里
2.
Method类:
通过Method可以执行某个目标类的方法,Method.invoke(目标对象,方法参数)
3.Proxy类:
核心对象,使用静态方法newProxyInstance()
创建代理对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
参数分析:
- ClassLoader loader:类加载器,负责向内存中加载对象,使用反射获取对象的ClassLoader
- Class<?>[] interfaces通过反射获取的目标对象实现的接口
- InvocationHandler h我们自己写的代理类需要完成的功能
二、使用步骤
1.
创建接口,定义目标类要完成的功能
2.创建目标类实现接口
3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
调用目标方法
增强功能
4.
使用Proxy类的静态方法,创建代理类对象,并把返回值转为接口类型
代码演示:
//演示动态代理
public class DynamicProxyTest {
public static void main(String[] args) {
//被代理的对象
Login login = new LoginImpl();
//创建代理对象 Proxy newProxyInstance
Object dynamicProxy = Proxy.newProxyInstance(LoginImpl.class.getClassLoader(),
LoginImpl.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
System.out.println("动态代理的前置增加功能");
result = method.invoke(login, args);
System.out.println("动态代理的后置增加功能");
} catch (IllegalAccessException e) {
e.printStackTrace();
// 异常增强
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
// 最终通知
}
return result;
}
});
//类型转换
Login proxyLogin = (Login)dynamicProxy;
//执行方法
proxyLogin.login("张三", "123456");
proxyLogin.register();
}
}