Proxy.newProxyInstance():jdk自带的代理方法)
也叫jdk代理,java底层封装了实现细节,格式固定,代码简单。直接调用java.lang.reflect.Proxy的静态方法newProxyInstance即可
1,被代理的对象必须是一个类,且必须有父接口;
2,被代理的类需要增强的方法必须在父接口中出现;
三个参数: 1,ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
2,Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
3,InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
@CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { //首先对InvocationHandler进行判空 Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }其实动态代理的思想就是:拿到被代理方法的字节码,然后通过反射得到该方法所在类的字节码,并创建对象,在使用method.invoke()方法的前后加上对原方法增强的代码
Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展. (也就是说Cglib这种代理方式不需要被代理对象实现接口或者继承类)
1,Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口**.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)**
2,Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.