JDK代理
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代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
(也就是说Cglib这种代理方式不需要被代理对象实现接口或者继承类)
1,Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口**.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)**
2,Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.