一、先定义一个动态代理类实现 InvocationHandler类,实现invoke方法
因为java动态代理是基于接口实现动态代理,所以被代理的类必须要基于某个接口
结果如下:
生成关键:
Proxy中的newProxyInstance()方法
在proxy中的getProxyClass0方法中,先去判断缓存中有无该对象
在proyClassCache.get()中关键点调动的apply()方法
最后实际调用的Proxy.apply()方法
调用ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags)生成代理对象
接下来验证生成的生成的类
通过ProxyGenerator.generateProxyClass()可以获取到生成的代理类字节码,并写入到本地
反编译查看详情
重点就是执行的InvocationHandler中的方法
接下来我们加载下刚刚生成代理类
一起执行结果如下:
代码如下:
public static void main(String[] args) throws Exception { Student student = new StudentImpl(); Student studentProxy = (Student) Proxy.newProxyInstance(student.getClass().getClassLoader(), new Class[]{Student.class}, (Object proxy, Method method, Object[] argss) -> { System.out.println("我是内存中的前置"); method.invoke(student); return proxy; }); studentProxy.getStudent(); String studentProxyClassName = studentProxy.getClass().toString(); studentProxyClassName = studentProxyClassName.substring(studentProxyClassName.lastIndexOf(".") + 2); byte[] bytes = ProxyGenerator.generateProxyClass(studentProxyClassName,new Class[]{Student.class}); Files.write(Paths.get("/Volumes/Mac/www/"+studentProxyClassName+".class"),bytes); URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL("file:/Volumes/Mac/www/")}); Class<?> proxy = classLoader.loadClass("Proxy0"); Constructor<?> declaredConstructors = proxy.getConstructor(InvocationHandler.class); Student student1 = (Student) declaredConstructors.newInstance(new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] argss) throws Throwable { System.out.println("我是加载class文件的前置"); method.invoke(student, argss); return proxy; } }); student1.getStudent(); }